003
23.12.2006, 21:08
feigling
|
#define HTTP_GET "GET %s HTTP/1.1\n" #define HTTP_HOST "HOST: %s\n"
int download_file(char *url) { char host[MAXLEN] = {0}, path[MAXLEN] = {0}, file[MAXLEN] = {0}; char buffer[MAXLEN], timestr[30], filename[MAXLEN], c; int res, recv_data = 0, http_socket; unsigned long file_size = -1; struct hostent *he = NULL; struct sockaddr_in sa; unsigned int pos; FILE *targetfile;
if(strstr(url, "http://") == url) url += 7;
/* Parse host/ip, path of the file and filename */ strncpy(host, url, strchr(url, '/') - url); strncpy(path, strchr(url, '/'), strlen(url) - (strchr(url, '/') - url)); strncpy(file, strrchr(url, '/') + 1, strlen(url) - (strrchr(url, '/') - url));
/* Connect to the server */ if(!(http_socket = socket(AF_INET, SOCK_STREAM, 0))) { log_append(log_main, LOG_ERROR, "download_file().socket() returned errno %d (%s).", errno, strerror(errno)); return 1; }
memset(&sa, 0, sizeof(struct sockaddr));
sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY;
bind(http_socket, (struct sockaddr *) &sa, sizeof(sa));
memset(&sa, 0, sizeof(struct sockaddr));
sa.sin_family = AF_INET; sa.sin_port = htons(80);
if(!(he = gethostbyname(host))) { if((sa.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { log_append(log_main, LOG_ERROR, "Unable to resolve hostname - download_file()."); return 2; } } else { bcopy(he->h_addr,(struct in_addr *) &sa.sin_addr, he->h_length); }
if(connect(http_socket,(struct sockaddr *) &sa, sizeof(sa)) < 0) { log_append(log_main, LOG_ERROR, "Unable to connect: errno %d (%s) - download_file().", errno, strerror(errno)); return 3; }
/* Send the required http lines */ snprintf(buffer, sizeof(buffer), HTTP_GET, path); send(http_socket, buffer, strlen(buffer), 0); snprintf(buffer, sizeof(buffer), HTTP_HOST, host); send(http_socket, buffer, strlen(buffer), 0); snprintf(buffer, sizeof(buffer), "\r\n"); send(http_socket, buffer, strlen(buffer), 0);
/* Receive -> open the file and wait for the reply */ time_t local = time(NULL); strftime(timestr, sizeof(timestr), "%m-%d-%Y--%H-%M-%S", localtime(&local)); snprintf(filename, sizeof(filename), "%s--%s", timestr, file); targetfile = fopen(filename, "w");
while(1) { memset(buffer, 0, sizeof(buffer)); pos = 0;
while(1) { if((res = recv(http_socket, &c, 1, 0)) <= 0) { log_append(log_main, LOG_ERROR, "download_file().recv() <= 0 - lost connection."); fclose(targetfile); remove(filename); close(http_socket); return 4; }
if(!recv_data) { if(c == '\n' || c == '\0') break;
if(c == '\r') continue;
buffer[pos++] = c; } else { fprintf(targetfile, "%c", c);
/* Decrease file_size and exit both loops when it's 0 */ if(!--file_size) break; } }
if(!recv_data) { char *argv[256]; int argc;
buffer[pos] = '\0'; argc = split_string(buffer, argv);
/* Check if the url is ok */ if(!strcmp(argv[0], "HTTP/1.1") && strcmp(argv[1], "200")) { log_append(log_main, LOG_ERROR, "Download failed. Server returned status %s.", argv[1]); fclose(targetfile); remove(filename); close(http_socket); return 5; }
/* Save the file size */ if(!strcmp(argv[0], "Content-Length:")) file_size = strtoul(argv[1], NULL, 0); /* All following lines are data we need to save to the file */ if(!strcmp(argv[0], "")) recv_data = 1; }
if(!file_size) break; }
fclose(targetfile); close(http_socket);
return 0; }
Das ist der C-Code zum Downloaden von Dateien aus dem Inet von mir. Er ist weder besonders optimiert (if((res = recv(http_socket, &c, 1, 0)) <= 0) = böse), aber dürfte ausreichen, dir zu zeigen, wie man etwas mit Sockets macht. Das musst du genauso für SMTP machen, nur halt senden anstatt empfangen. split_string trennt nur "123 4 5 6" in "123" "4" "5" "6". Viel Spass.
--
Dieser Beitrag wurde am 23.12.2006 um 23:52 von feigling bearbeitet.
|