Mercurial > gftp.yaz
diff lib/protocols.c @ 168:c505d9ba9d53
2003-6-6 Brian Masney <masneyb@gftp.org>
* lib/gftp.h - if USE_SSL is defined, include the OpenSSL headers.
Added read_function, write_function and post_connect function pointers
to gftp_request structure. Added SSL object to gftp_request structure
if USE_SSL is defined. Added protocol number and init function
declarations for the HTTPS protocol
* lib/options.h - added HTTPS to the list of supported protocols
* lib/protocols.c lib/cache.c lib/rfc2068.c lib/rfc959.c lib/sshv2.c -
renamed gftp_read(), gftp_write() and gftp_set_sockblocking() to
gftp_fd_read(), gftp_fd_write() and gftp_fd_set_sockblocking()
respectively
* lib/bookmark.c lib/local.c
* lib/misc.c lib/rfc2068.c - moved base64_encode() to misc.c
* lib/protocols.c - improved parsing of URLs. Rather than calling
gftp_read() or gftp_write() directly, call the read_function or
write_function that is set in the request structure. Expanded tabs
to spaces. Cleanup for parsing of timestamps. In
gftp_connect_server(), if a post_connect function pointer is set,
call it after we are connected to the server. Improvements to
gftp_get_line ().
* lib/httpcommon.h lib/rfc2068.c - moved rfc2068_params structure to
httpcommon.h. Fix for chunked file transfers, they were not handled
at all before. Made the I/O calls a little more generic so that we can
read from either a socket or a SSL connection.
* lib/sslcommon.c - added generic SSL layer
* lib/https.c - added support for the HTTPS protocol. It piggy backs
off of the existing HTTP support and uses the generic SSL layer
* src/gtk/bookmarks.c src/gtk/chmod_dialog.c src/gtk/gftp-gtk.c
src/gtk/menu-items.c src/gtk/misc-gtk.c src/gtk/options_dialog.c
src/gtk/view_dialog.c - set the window icon name to the gFTP <version>
* configure.in - added lib back to SUBDIRS (oops)
* lib/Makefile.am - added https.c, sslcommon.c and httpcommon.h
author | masneyb |
---|---|
date | Sun, 08 Jun 2003 15:04:40 +0000 |
parents | 2f15b3000dbc |
children | d40f9db52cdf |
line wrap: on
line diff
--- a/lib/protocols.c Wed May 28 18:37:28 2003 +0000 +++ b/lib/protocols.c Sun Jun 08 15:04:40 2003 +0000 @@ -128,6 +128,14 @@ #endif request->hostp = NULL; +#ifdef USE_SSL + if (request->ssl != NULL) + { + SSL_free (request->ssl); + request->ssl = NULL; + } +#endif + request->cached = 0; if (request->disconnect == NULL) return; @@ -227,7 +235,7 @@ if (request->get_next_file_chunk != NULL) return (request->get_next_file_chunk (request, buf, size)); - return (gftp_read (request, buf, size, request->datafd)); + return (request->read_function (request, buf, size, request->datafd)); } @@ -243,7 +251,7 @@ if (size == 0) return (0); - return (gftp_write (request, buf, size, request->datafd)); + return (request->write_function (request, buf, size, request->datafd)); } @@ -364,7 +372,7 @@ if (ret >= 0 && !request->cached && request->cachefd > 0 && request->last_dir_entry != NULL) { - if (gftp_write (request, request->last_dir_entry, + if (gftp_fd_write (request, request->last_dir_entry, request->last_dir_entry_len, request->cachefd) < 0) { request->logging_function (gftp_logging_error, request->user_data, @@ -458,9 +466,9 @@ int gftp_parse_url (gftp_request * request, const char *url) { - char *pos, *endpos, *endhostpos, *str, tempchar, *default_protocol; + char *pos, *endpos, *endhostpos, tempchar, *default_protocol, *stpos; gftp_logging_func logging_function; - const char *stpos; + const char *cpos; int len, i; g_return_val_if_fail (request != NULL, GFTP_EFATAL); @@ -470,7 +478,10 @@ gftp_request_destroy (request, 0); request->logging_function = logging_function; - for (stpos = url; *stpos == ' '; stpos++); + for (cpos = url; *cpos == ' '; cpos++); + stpos = g_strdup (cpos); + for (pos = stpos + strlen (stpos) - 1; *pos == ' '; pos--) + *pos = '\0'; i = GFTP_FTP_NUM; @@ -484,9 +495,13 @@ break; } + *pos = ':'; + if (gftp_protocols[i].url_prefix == NULL) - return (GFTP_EFATAL); - *pos = ':'; + { + g_free (stpos); + return (GFTP_EFATAL); + } } else { @@ -509,48 +524,47 @@ gftp_protocols[i].init (request); if (request->parse_url != NULL) - return (request->parse_url (request, url)); + { + g_free (stpos); + return (request->parse_url (request, url)); + } + + pos = stpos; + len = strlen (request->url_prefix); + if (strncmp (pos, request->url_prefix, len) == 0 && + strncmp (pos + len, "://", 3) == 0) + pos += len + 3; if (i == GFTP_LOCAL_NUM) { - request->directory = g_strdup (stpos + 7); + request->directory = g_strdup (pos); + g_free (stpos); return (0); } - for (; *stpos == ' '; stpos++); - str = g_strdup (stpos); - for (pos = str + strlen (str) - 1; *pos == ' '; pos--) - *pos = '\0'; - - pos = str; - len = strlen (request->url_prefix); - if (strncmp (pos, request->url_prefix, len) == 0 - && strncmp (pos + len, "://", 3) == 0) - pos += len + 3; - if ((endhostpos = strchr (pos, '@')) != NULL) { /* A user/password was entered */ if ((endpos = strchr (pos, ':')) == NULL || endhostpos < endpos) - { - /* No password was entered */ - gftp_set_password (request, ""); - endpos = endhostpos; - } + { + /* No password was entered */ + gftp_set_password (request, ""); + endpos = endhostpos; + } *endpos = '\0'; gftp_set_username (request, pos); pos = endpos + 1; if ((endpos = strchr (pos, '@')) != NULL) - { - if (strchr (endpos + 1, '@') != NULL) - endpos = strchr (endpos + 1, '@'); - *endpos = '\0'; - gftp_set_password (request, pos); + { + if (strchr (endpos + 1, '@') != NULL) + endpos = strchr (endpos + 1, '@'); + *endpos = '\0'; + gftp_set_password (request, pos); - pos = endpos + 1; - } + pos = endpos + 1; + } } /* Now get the hostname and an optional port and optional directory */ @@ -572,7 +586,7 @@ } if ((endpos = strchr (pos, '/')) != NULL) gftp_set_directory (request, endpos); - g_free (str); + g_free (stpos); return (0); } @@ -635,11 +649,11 @@ if (request->sockfd <= 0 && !request->always_connected) { if (directory != request->directory) - { - if (request->directory) - g_free (request->directory); - request->directory = g_strdup (directory); - } + { + if (request->directory) + g_free (request->directory); + request->directory = g_strdup (directory); + } return (0); } else if (request->chdir == NULL) @@ -692,7 +706,7 @@ int gftp_rename_file (gftp_request * request, const char *oldname, - const char *newname) + const char *newname) { g_return_val_if_fail (request != NULL, GFTP_EFATAL); @@ -822,23 +836,23 @@ hostname = templist->data; if (hostname->domain && strlen (request->hostname) > strlen (hostname->domain)) - { - pos = request->hostname + strlen (request->hostname) - - strlen (hostname->domain); - if (strcmp (hostname->domain, pos) == 0) - return (0); - } + { + pos = request->hostname + strlen (request->hostname) - + strlen (hostname->domain); + if (strcmp (hostname->domain, pos) == 0) + return (0); + } if (hostname->ipv4_network_address != 0) - { - memcpy (addy, addr, sizeof (addy)); - netaddr = - (((addy[0] & 0xff) << 24) | ((addy[1] & 0xff) << 16) | - ((addy[2] & 0xff) << 8) | (addy[3] & 0xff)) & + { + memcpy (addy, addr, sizeof (addy)); + netaddr = + (((addy[0] & 0xff) << 24) | ((addy[1] & 0xff) << 16) | + ((addy[2] & 0xff) << 8) | (addy[3] & 0xff)) & hostname->ipv4_netmask; - if (netaddr == hostname->ipv4_network_address) - return (0); - } + if (netaddr == hostname->ipv4_network_address) + return (0); + } templist = templist->next; } @@ -894,6 +908,7 @@ struct tm curtime, *loctime; time_t t, ret; char *tmppos; + int i; memset (&curtime, 0, sizeof (curtime)); curtime.tm_isdst = -1; @@ -937,7 +952,8 @@ /* We cannot parse this date format. So, just skip this date field and continue to the next token. This is mainly for the HTTP support */ - for (*endpos = str; **endpos != ' ' && **endpos != '\t' && **endpos != '\0'; *endpos++); + for (i=0, *endpos = str; (*endpos)[i] != ' ' && (*endpos)[i] != '\t' && (*endpos)[i] != '\0'; i++); + endpos += i; } else *endpos = tmppos; @@ -1033,17 +1049,17 @@ { startpos++; switch (*startpos) - { - case '/': - *fle->attribs = 'd'; - break; - case 's': - fle->size = strtol (startpos + 1, NULL, 10); - break; - case 'm': - fle->datetime = strtol (startpos + 1, NULL, 10); - break; - } + { + case '/': + *fle->attribs = 'd'; + break; + case 's': + fle->size = strtol (startpos + 1, NULL, 10); + break; + case 'm': + fle->datetime = strtol (startpos + 1, NULL, 10); + break; + } startpos = strchr (startpos, ','); } if ((startpos = strchr (str, 9)) == NULL) @@ -1101,20 +1117,20 @@ /* Copy the user that owns this file */ if ((startpos = copy_token (&fle->user, startpos)) == NULL) - return (GFTP_EFATAL); + return (GFTP_EFATAL); /* Copy the group that owns this file */ if ((startpos = copy_token (&fle->group, startpos)) == NULL) - return (GFTP_EFATAL); + return (GFTP_EFATAL); } else { fle->group = g_strdup (_("unknown")); if (cols == 8) - { - if ((startpos = copy_token (&fle->user, startpos)) == NULL) - return (GFTP_EFATAL); - } + { + if ((startpos = copy_token (&fle->user, startpos)) == NULL) + return (GFTP_EFATAL); + } else fle->user = g_strdup (_("unknown")); startpos = goto_next_token (startpos); @@ -1141,18 +1157,18 @@ startpos = endpos + 1; while (*startpos == ' ') - startpos++; + startpos++; /* Get the minor number */ if ((endpos = strchr (startpos, ' ')) == NULL) - return (GFTP_EFATAL); + return (GFTP_EFATAL); fle->size |= strtol (startpos, NULL, 10) & 0xFF; } else { /* This is a regular file */ if ((endpos = strchr (startpos, ' ')) == NULL) - return (GFTP_EFATAL); + return (GFTP_EFATAL); fle->size = strtol (startpos, NULL, 10); } @@ -1599,15 +1615,15 @@ snprintf (serv, sizeof (serv), "%d", port); request->logging_function (gftp_logging_misc, request->user_data, - _("Looking up %s\n"), connect_host); + _("Looking up %s\n"), connect_host); if ((errnum = getaddrinfo (connect_host, serv, &hints, &request->hostp)) != 0) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot look up hostname %s: %s\n"), - connect_host, gai_strerror (errnum)); - return (GFTP_ERETRYABLE); - } + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot look up hostname %s: %s\n"), + connect_host, gai_strerror (errnum)); + return (GFTP_ERETRYABLE); + } } disphost = connect_host; @@ -1621,23 +1637,23 @@ if ((sock = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) { - request->logging_function (gftp_logging_error, request->user_data, + request->logging_function (gftp_logging_error, request->user_data, _("Failed to create a socket: %s\n"), g_strerror (errno)); continue; } request->logging_function (gftp_logging_misc, request->user_data, - _("Trying %s:%d\n"), disphost, port); + _("Trying %s:%d\n"), disphost, port); if (connect (sock, res->ai_addr, res->ai_addrlen) == -1) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot connect to %s: %s\n"), - disphost, g_strerror (errno)); + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot connect to %s: %s\n"), + disphost, g_strerror (errno)); close (sock); continue; - } + } break; } @@ -1708,7 +1724,7 @@ if (request->hostp == NULL) { request->logging_function (gftp_logging_misc, request->user_data, - _("Looking up %s\n"), connect_host); + _("Looking up %s\n"), connect_host); if (!(request->hostp = r_gethostbyname (connect_host, &request->host, NULL))) { @@ -1749,15 +1765,20 @@ #endif /* HAVE_GETADDRINFO */ request->logging_function (gftp_logging_misc, request->user_data, - _("Connected to %s:%d\n"), connect_host, port); + _("Connected to %s:%d\n"), connect_host, port); - if (gftp_set_sockblocking (request, sock, 1) < 0) + if (gftp_fd_set_sockblocking (request, sock, 1) < 0) { close (sock); return (GFTP_ERETRYABLE); } - return (sock); + request->sockfd = sock; + + if (request->post_connect != NULL) + return (request->post_connect (request)); + + return (0); } @@ -1823,27 +1844,35 @@ gftp_get_line (gftp_request * request, gftp_getline_buffer ** rbuf, char * str, size_t len, int fd) { - ssize_t ret, retval, rlen, copysize; + ssize_t ret, retval, rlen; char *pos, *nextpos; + ssize_t (*read_function) (gftp_request * request, void *ptr, size_t size, + int fd); + + if (request == NULL || request->read_function == NULL) + read_function = gftp_fd_read; + else + read_function = request->read_function; if (*rbuf == NULL) { *rbuf = g_malloc0 (sizeof (**rbuf)); (*rbuf)->max_bufsize = len; (*rbuf)->buffer = g_malloc ((*rbuf)->max_bufsize + 1); - if ((ret = gftp_read (request, (*rbuf)->buffer, (*rbuf)->max_bufsize, - fd)) <= 0) + + if ((ret = read_function (request, (*rbuf)->buffer, + (*rbuf)->max_bufsize, fd)) <= 0) { gftp_free_getline_buffer (rbuf); return (ret); } + (*rbuf)->buffer[ret] = '\0'; (*rbuf)->cur_bufsize = ret; (*rbuf)->curpos = (*rbuf)->buffer; } retval = GFTP_ERETRYABLE; - do { if ((*rbuf)->cur_bufsize > 0 && @@ -1852,6 +1881,11 @@ (*rbuf)->max_bufsize == (*rbuf)->cur_bufsize))) { if (pos != NULL) + retval = pos - (*rbuf)->curpos + 1; + else + retval = (*rbuf)->cur_bufsize; + + if (pos != NULL) { nextpos = pos + 1; if (pos > (*rbuf)->curpos && *(pos - 1) == '\r') @@ -1862,16 +1896,12 @@ nextpos = NULL; strncpy (str, (*rbuf)->curpos, len); - retval = pos - (*rbuf)->curpos > len ? len : pos - (*rbuf)->curpos; + (*rbuf)->cur_bufsize -= retval; - if (pos != NULL) - { - if (nextpos - (*rbuf)->buffer >= (*rbuf)->cur_bufsize) - (*rbuf)->cur_bufsize = 0; - else - (*rbuf)->curpos = nextpos; - } - + if (nextpos != NULL) + (*rbuf)->curpos = nextpos; + else + (*rbuf)->cur_bufsize = 0; break; } else @@ -1880,24 +1910,29 @@ { rlen = (*rbuf)->max_bufsize; pos = (*rbuf)->buffer; - copysize = 0; } else { - copysize = (*rbuf)->cur_bufsize - ((*rbuf)->curpos - (*rbuf)->buffer); - memmove ((*rbuf)->buffer, (*rbuf)->curpos, copysize); - pos = (*rbuf)->buffer + copysize; - rlen = (*rbuf)->max_bufsize - copysize; + memmove ((*rbuf)->buffer, (*rbuf)->curpos, (*rbuf)->cur_bufsize); + pos = (*rbuf)->buffer + (*rbuf)->cur_bufsize; + rlen = (*rbuf)->max_bufsize - (*rbuf)->cur_bufsize; } + (*rbuf)->curpos = (*rbuf)->buffer; - if ((ret = gftp_read (request, pos, rlen, fd)) <= 0) + if ((ret = read_function (request, pos, rlen, fd)) < 0) { gftp_free_getline_buffer (rbuf); return (ret); } - (*rbuf)->buffer[ret + copysize] = '\0'; - (*rbuf)->cur_bufsize = ret + copysize; + else if (ret == 0 && (*rbuf)->cur_bufsize == 0) + { + gftp_free_getline_buffer (rbuf); + return (ret); + } + + (*rbuf)->buffer[ret + (*rbuf)->cur_bufsize] = '\0'; + (*rbuf)->cur_bufsize += ret; } } while (retval == GFTP_ERETRYABLE); @@ -1907,7 +1942,7 @@ ssize_t -gftp_read (gftp_request * request, void *ptr, size_t size, int fd) +gftp_fd_read (gftp_request * request, void *ptr, size_t size, int fd) { long network_timeout; struct timeval tv; @@ -1977,7 +2012,7 @@ ssize_t -gftp_write (gftp_request * request, const char *ptr, size_t size, int fd) +gftp_fd_write (gftp_request * request, const char *ptr, size_t size, int fd) { long network_timeout; struct timeval tv; @@ -2061,14 +2096,14 @@ tempstr = g_strdup_vprintf (fmt, argp); va_end (argp); - ret = gftp_write (request, tempstr, strlen (tempstr), fd); + ret = request->write_function (request, tempstr, strlen (tempstr), fd); g_free (tempstr); return (ret); } int -gftp_set_sockblocking (gftp_request * request, int fd, int non_blocking) +gftp_fd_set_sockblocking (gftp_request * request, int fd, int non_blocking) { int flags;