From 9d9ffa6cecb7d1a5e875c9d39fb3f4a0580c52df Mon Sep 17 00:00:00 2001 From: Judd Vinet Date: Mon, 15 Sep 2003 04:58:02 +0000 Subject: Imported from pacman-2.6.1.tar.gz --- libftp/ftplib.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) (limited to 'libftp/ftplib.c') diff --git a/libftp/ftplib.c b/libftp/ftplib.c index d8c25f58..f312db89 100644 --- a/libftp/ftplib.c +++ b/libftp/ftplib.c @@ -1309,3 +1309,245 @@ GLOBALDEF void FtpQuit(netbuf *nControl) free(nControl->buf); free(nControl); } + +/* + * HttpConnect - connect to remote server + * + * return 1 if connected, 0 if not + */ +GLOBALREF int HttpConnect(const char *host, netbuf **nControl) +{ + int sControl; + struct sockaddr_in sin; + struct hostent *phe; + struct servent *pse; + int on=1; + netbuf *ctrl; + char *lhost; + char *pnum; + + memset(&sin,0,sizeof(sin)); + sin.sin_family = AF_INET; + lhost = strdup(host); + pnum = strchr(lhost,':'); + if (pnum == NULL) + { +#if defined(VMS) + sin.sin_port = htons(21); +#else + if ((pse = getservbyname("http","tcp")) == NULL) + { + perror("getservbyname"); + return 0; + } + sin.sin_port = pse->s_port; +#endif + } + else + { + *pnum++ = '\0'; + if (isdigit(*pnum)) + sin.sin_port = htons(atoi(pnum)); + else + { + pse = getservbyname(pnum,"tcp"); + sin.sin_port = pse->s_port; + } + } + if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1) + { + if ((phe = gethostbyname(lhost)) == NULL) + { + perror("gethostbyname"); + return 0; + } + memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); + } + free(lhost); + sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sControl == -1) + { + perror("socket"); + return 0; + } + if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, + SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1) + { + perror("setsockopt"); + net_close(sControl); + return 0; + } + if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1) + { + perror("connect"); + net_close(sControl); + return 0; + } + ctrl = calloc(1,sizeof(netbuf)); + if (ctrl == NULL) + { + perror("calloc"); + net_close(sControl); + return 0; + } + ctrl->buf = NULL; + ctrl->handle = sControl; + ctrl->dir = FTPLIB_CONTROL; + ctrl->ctrl = NULL; + ctrl->cmode = FTPLIB_DEFMODE; + ctrl->idlecb = NULL; + ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0; + ctrl->idlearg = NULL; + ctrl->xfered = 0; + ctrl->xfered1 = 0; + ctrl->cbbytes = 0; + *nControl = ctrl; + return 1; +} + +/* + * HttpSendCmd - send a command + * + * return 1 if proper response received, 0 otherwise + */ +static int HttpSendCmd(const char *cmd, char expresp, netbuf *nControl) +{ + int ret = 0; + char *buf = nControl->response; + if (nControl->dir != FTPLIB_CONTROL) + return 0; + if (ftplib_debug > 2) + fprintf(stderr,"%s\n",cmd); + if (net_write(nControl->handle,cmd,strlen(cmd)) <= 0) + { + perror("write"); + return 0; + } + while (ret < 256) { + if (socket_wait(nControl) != 1) + return 0; + if (net_read(nControl->handle,buf,1) != 1) + break; + ret++; + if (*buf == '\r') continue; + if (*buf == '\n') break; + buf++; + } + *buf = 0; + if (nControl->response[9] == expresp) + return 1; + return 0; +} + +/* + * HttpXfer - issue a command and transfer data + * + * return 1 if successful, 0 otherwise + */ +static int HttpXfer(const char *localfile, const char *path, + netbuf *nControl, int typ, int mode) +{ + int l,c; + char *dbuf; + FILE *local = NULL; + int rv=1; + + if (localfile != NULL) + { + char ac[4] = "a"; + if (typ == FTPLIB_FILE_WRITE) + ac[0] = 'r'; + if (mode == FTPLIB_IMAGE) + ac[1] = 'b'; + local = fopen(localfile, ac); + if (local == NULL) + { + strncpy(nControl->response, strerror(errno), + sizeof(nControl->response)); + return 0; + } + } + if (local == NULL) + local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; + dbuf = malloc(FTPLIB_BUFSIZ); + if (typ == FTPLIB_FILE_WRITE) + { + while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) + if ((c = FtpWrite(dbuf, l, nControl)) < l) + { + printf("short write: passed %d, wrote %d\n", l, c); + rv = 0; + break; + } + } + else + { + nControl->dir = FTPLIB_READ; + while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nControl)) > 0) + if (fwrite(dbuf, 1, l, local) <= 0) + { + perror("localfile write"); + rv = 0; + break; + } + } + free(dbuf); + fflush(local); + if (localfile != NULL) + fclose(local); + free(nControl->data); + return rv; +} + +/* + * HttpGet - issue a GET command and write received data to output + * + * return 1 if successful, 0 otherwise + */ +GLOBALREF int HttpGet(const char *outputfile, const char *path, int *size, + netbuf *nControl) +{ + char buf[256]; + + sprintf(buf, "GET %s HTTP/1.0\r\n\r\n\r\n", path); + if(!HttpSendCmd(buf,'2',nControl)) + { + if (nControl->response[9] == '3') + printf("redirection not supported\n"); + return 0; + } + + while (1) + { + int ret = 0; + char *buf = nControl->response; + while (ret < 256) { + if (socket_wait(nControl) != 1) + return 0; + if (net_read(nControl->handle,buf,1) != 1) + break; + ret++; + if (*buf == '\r') continue; + if (*buf == '\n') break; + buf++; + } + *buf = 0; + if (strstr(nControl->response,"Content-Length")) + sscanf(nControl->response,"Content-Length: %d",size); + if (strlen(nControl->response) == 0) + break; + } + + return HttpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, FTPLIB_IMAGE); +} + +/* + * HttpQuit - disconnect from remote + * + * return 1 if successful, 0 otherwise + */ +GLOBALREF void HttpQuit(netbuf *nControl) +{ + net_close(nControl->handle); + free(nControl); +} -- cgit v1.2.3-24-g4f1b