URL url_http_open(char *name) { URL_http *url; SOCKET fd; char *host, *path = NULL, *p; unsigned short port; char buff[BUFSIZ]; char wwwserver[256]; int n; #ifdef DEBUG printf("url_http_open(%s)\n", name); #endif /* DEBUG */ url = (URL_http *)alloc_url(sizeof(URL_http)); if(url == NULL) { url_errno = errno; return NULL; } /* common members */ URLm(url, type) = URL_http_t; URLm(url, url_read) = url_http_read; URLm(url, url_gets) = url_http_gets; URLm(url, url_fgetc) = url_http_fgetc; URLm(url, url_seek) = NULL; URLm(url, url_tell) = NULL; URLm(url, url_close) = url_http_close; /* private members */ url->fp = NULL; if(url_http_proxy_host) { char *q; int len; host = url_http_proxy_host; port = url_http_proxy_port; p = name; if(strncmp(p, "http://", 7) == 0) p += 7; for(q = p; *q && *q != ':' && *q != '/'; q++) ; len = q - p; if(len >= sizeof(wwwserver) - 1) { /* What?? */ strcpy(wwwserver, "localhost"); } else { strncpy(wwwserver, p, len); } } else { if(strncmp(name, "http://", 7) == 0) name += 7; n = strlen(name); if(n + REQUEST_OFFSET >= BUFSIZ) { url_http_close((URL)url); url_errno = URLERR_URLTOOLONG; errno = ENOENT; return NULL; } memcpy(buff, name, n + 1); host = buff; for(p = host; *p && *p != ':' && *p != '/'; p++) ; if(*p == ':') { char *pp; *p++ = '\0'; /* terminate `host' string */ port = atoi(p); pp = strchr(p, '/'); if(pp == NULL) p[0] = '\0'; else p = pp; } else port = 80; path = p; if(*path == '\0') *(path + 1) = '\0'; *path = '\0'; /* terminate `host' string */ strncpy(wwwserver, host, sizeof(wwwserver)); } #ifdef DEBUG printf("open(host=`%s', port=`%d')\n", host, port); #endif /* DEBUG */ #ifdef __W32__ timeout_flag = 0; fd = open_socket(host, port); #else timeout_flag = 0; signal(SIGALRM, timeout); alarm(ALARM_TIMEOUT); fd = open_socket(host, port); alarm(0); signal(SIGALRM, SIG_DFL); #endif /* __W32__ */ if(fd == (SOCKET)-1) { VOLATILE_TOUCH(timeout_flag); #ifdef ETIMEDOUT if(timeout_flag) errno = ETIMEDOUT; #endif /* ETIMEDOUT */ if(errno) url_errno = errno; else { url_errno = URLERR_CANTOPEN; errno = ENOENT; } url_http_close((URL)url); return NULL; } if((url->fp = socket_fdopen(fd, "rb")) == NULL) { url_errno = errno; closesocket(fd); url_http_close((URL)url); errno = url_errno; return NULL; } if(url_http_proxy_host) sprintf(buff, "GET %s HTTP/1.0\r\n", name); else { *path = '/'; sprintf(buff, "GET %s HTTP/1.0\r\n", path); } socket_write(fd, buff, (long)strlen(buff)); #ifdef DEBUG printf("HTTP<%s", buff); #endif /* DEBUG */ if(url_user_agent) { sprintf(buff, "User-Agent: %s\r\n", url_user_agent); socket_write(fd, buff, (long)strlen(buff)); #ifdef DEBUG printf("HTTP<%s", buff); #endif /* DEBUG */ } /* Host field */ sprintf(buff, "Host: %s\r\n", wwwserver); socket_write(fd, buff, (long)strlen(buff)); #ifdef DEBUG printf("HTTP<%s", buff); #endif /* DEBUG */ /* End of header */ socket_write(fd, "\r\n", 2); socket_shutdown(fd, 1); if(socket_fgets(buff, BUFSIZ, url->fp) == NULL) { if(errno) url_errno = errno; else { url_errno = URLERR_CANTOPEN; errno = ENOENT; } url_http_close((URL)url); return NULL; } #ifdef DEBUG printf("HTTP>%s", buff); #endif /* DEBUG */ p = buff; if(strncmp(p, "HTTP/1.0 ", 9) == 0 || strncmp(p, "HTTP/1.1 ", 9) == 0) p += 9; if(strncmp(p, "200", 3) != 0) /* Not success */ { url_http_close((URL)url); url_errno = errno = ENOENT; return NULL; } /* Skip mime header */ while(socket_fgets(buff, BUFSIZ, url->fp) != NULL) { if(buff[0] == '\n' || (buff[0] == '\r' && buff[1] == '\n')) break; /* end of heaer */ #ifdef DEBUG printf("HTTP>%s", buff); #endif /* DEBUG */ } #ifdef __W32__ return url_buff_open((URL)url, 1); #else return (URL)url; #endif /* __W32__ */ }
static NewsConnection *open_news_server(char *host, unsigned short port) { NewsConnection *p; char buff[512]; for(p = connection_cache; p != NULL; p = p->next) { if(p->status == 0 && strcmp(p->host, host) == 0 && p->port == port) { p->status = 1; return p; } } for(p = connection_cache; p != NULL; p = p->next) if(p->status == -1) break; if(p == NULL) { if((p = (NewsConnection *)safe_malloc(sizeof(NewsConnection))) == NULL) return NULL; p->next = connection_cache; connection_cache = p; p->status = -1; } if((p->host = safe_strdup(host)) == NULL) return NULL; p->port = port; #ifdef __W32__ timeout_flag = 0; p->fd = open_socket(host, port); #else timeout_flag = 0; signal(SIGALRM, timeout); alarm(ALARM_TIMEOUT); p->fd = open_socket(host, port); alarm(0); signal(SIGALRM, SIG_DFL); #endif /* __W32__ */ if(p->fd == (SOCKET)-1) { int save_errno; VOLATILE_TOUCH(timeout_flag); #ifdef ETIMEDOUT if(timeout_flag) errno = ETIMEDOUT; #endif /* ETIMEDOUT */ if(errno) url_errno = errno; else { url_errno = URLERR_CANTOPEN; errno = ENOENT; } #ifdef DEBUG perror(host); #endif /* DEBUG */ save_errno = errno; free(p->host); errno = save_errno; return NULL; } if((p->fp = socket_fdopen(p->fd, "rb")) == NULL) { url_errno = errno; closesocket(p->fd); free(p->host); errno = url_errno; return NULL; } buff[0] = '\0'; if(socket_fgets(buff, sizeof(buff), p->fp) == NULL) { url_errno = errno; closesocket(p->fd); socket_fclose(p->fp); free(p->host); errno = url_errno; return NULL; } #ifdef DEBUG fprintf(stderr, "Connect status: %s", buff); #endif /* DEBUG */ if(buff[0] != NNTP_OK_ID) { closesocket(p->fd); socket_fclose(p->fp); free(p->host); url_errno = URLERR_CANTOPEN; errno = ENOENT; return NULL; } p->status = 1; return p; }