Mercurial > gftp.yaz
view lib/cache.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 | 76e2b58a9440 |
children | 8d933999bba6 |
line wrap: on
line source
/*****************************************************************************/ /* cache.c - contains the cache routines */ /* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ /*****************************************************************************/ #include "gftp.h" static const char cvsid[] = "$Id$"; struct gftp_cache_entry_tag { char *url, *file; int server_type; char *pos1, *pos2; }; typedef struct gftp_cache_entry_tag gftp_cache_entry; static int gftp_parse_cache_line (gftp_request * request, gftp_cache_entry * centry, char *line) { char *pos; memset (centry, 0, sizeof (*centry)); if ((pos = strchr (line, '\t')) == NULL || *(pos + 1) == '\0') { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Invalid line %s in cache index file\n"), line); return (-1); } centry->pos1 = pos; *pos++ = '\0'; centry->url = line; centry->file = pos; if ((pos = strchr (pos, '\t')) == NULL || *(pos + 1) == '\0') { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Invalid line %s in cache index file\n"), line); return (-1); } centry->pos2 = pos; *pos++ = '\0'; centry->server_type = strtol (pos, NULL, 10); return (0); } void gftp_restore_cache_line (gftp_cache_entry * centry, char *line) { if (centry->pos1 != NULL) *centry->pos1 = '\t'; if (centry->pos2 != NULL) *centry->pos2 = '\t'; } int gftp_new_cache_entry (gftp_request * request) { char *cachedir, *tempstr, *temp1str; int cache_fd, fd; ssize_t ret; cachedir = expand_path (BASE_CONF_DIR "/cache"); if (access (cachedir, F_OK) == -1) { if (mkdir (cachedir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Could not make directory %s: %s\n"), cachedir, g_strerror (errno)); return (-1); } } tempstr = g_strdup_printf ("%s/index.db", cachedir); if ((fd = open (tempstr, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Cannot open local file %s: %s\n"), tempstr, g_strerror (errno)); g_free (tempstr); g_free (cachedir); return (-1); } g_free (tempstr); tempstr = g_strdup_printf ("%s/cache.XXXXXX", cachedir); if ((cache_fd = mkstemp (tempstr)) < 0) { g_free (tempstr); if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Cannot create temporary file: %s\n"), g_strerror (errno)); return (-1); } g_free (cachedir); lseek (fd, 0, SEEK_END); temp1str = g_strdup_printf ("%s://%s@%s:%d%s\t%s\t%d\n", request->url_prefix, request->username == NULL ? "" : request->username, request->hostname == NULL ? "" : request->hostname, request->port, request->directory == NULL ? "" : request->directory, tempstr, request->server_type); g_free (tempstr); ret = gftp_fd_write (NULL, temp1str, strlen (temp1str), fd); g_free (temp1str); if (close (fd) != 0 || ret < 0) { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error closing file descriptor: %s\n"), g_strerror (errno)); close (cache_fd); return (-1); } return (cache_fd); } int gftp_find_cache_entry (gftp_request * request) { char *indexfile, buf[BUFSIZ], description[BUFSIZ]; gftp_getline_buffer * rbuf; gftp_cache_entry centry; int indexfd, cachefd; g_snprintf (description, sizeof (description), "%s://%s@%s:%d%s", request->url_prefix, request->username == NULL ? "" : request->username, request->hostname == NULL ? "" : request->hostname, request->port, request->directory == NULL ? "" : request->directory); indexfile = expand_path (BASE_CONF_DIR "/cache/index.db"); if ((indexfd = open (indexfile, O_RDONLY)) == -1) { g_free (indexfile); return (-1); } g_free (indexfile); rbuf = NULL; while (gftp_get_line (NULL, &rbuf, buf, sizeof (buf), indexfd) > 0) { if (gftp_parse_cache_line (request, ¢ry, buf) < 0) continue; if (strcmp (description, centry.url) == 0) { if (close (indexfd) != 0) { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error closing file descriptor: %s\n"), g_strerror (errno)); return (-1); } if ((cachefd = open (centry.file, O_RDONLY)) == -1) { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Cannot open local file %s: %s\n"), centry.file, g_strerror (errno)); return (-1); } if (lseek (cachefd, 0, SEEK_END) == 0) { close (cachefd); return (-1); } if (lseek (cachefd, 0, SEEK_SET) == -1) { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Cannot seek on file %s: %s\n"), centry.file, g_strerror (errno)); } request->server_type = centry.server_type; return (cachefd); } } close (indexfd); return (-1); } void gftp_clear_cache_files (void) { char *indexfile, buf[BUFSIZ]; gftp_getline_buffer * rbuf; gftp_cache_entry centry; int indexfd; indexfile = expand_path (BASE_CONF_DIR "/cache/index.db"); if ((indexfd = open (indexfile, O_RDONLY)) == -1) { g_free (indexfile); return; } rbuf = NULL; while (gftp_get_line (NULL, &rbuf, buf, sizeof (buf), indexfd) > 0) { if (gftp_parse_cache_line (NULL, ¢ry, buf) < 0) continue; unlink (centry.file); } close (indexfd); unlink (indexfile); g_free (indexfile); } void gftp_delete_cache_entry (gftp_request * request, int ignore_directory) { char *oldindexfile, *newindexfile, buf[BUFSIZ], description[BUFSIZ]; gftp_getline_buffer * rbuf; gftp_cache_entry centry; int indexfd, newfd; int remove; g_snprintf (description, sizeof (description), "%s://%s@%s:%d%s", request->url_prefix, request->username == NULL ? "" : request->username, request->hostname == NULL ? "" : request->hostname, request->port, ignore_directory || request->directory == NULL ? "" : request->directory); oldindexfile = expand_path (BASE_CONF_DIR "/cache/index.db"); if ((indexfd = open (oldindexfile, O_RDONLY)) == -1) { g_free (oldindexfile); return; } newindexfile = expand_path (BASE_CONF_DIR "/cache/index.db.new"); if ((newfd = open (newindexfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { if (request != NULL) request->logging_function (gftp_logging_error, request->user_data, _("Error: Cannot open local file %s: %s\n"), newindexfile, g_strerror (errno)); g_free (oldindexfile); g_free (newindexfile); return; } rbuf = NULL; while (gftp_get_line (NULL, &rbuf, buf, sizeof (buf) - 1, indexfd) > 0) { if (gftp_parse_cache_line (request, ¢ry, buf) < 0) continue; remove = 0; if (ignore_directory) { if (strncmp (centry.url, description, strlen (description)) == 0) remove = 1; } else { if (strcmp (centry.url, description) == 0) remove = 1; } if (remove) unlink (centry.file); else { /* Make sure when we call gftp_get_line() that we pass the read size as sizeof(buf) - 1 so that we'll have room to put the newline */ buf[strlen (buf)] = '\n'; /* Make sure we put the tabs back in the line. I do it this way so that I don't have to allocate memory again for each line as we read it */ gftp_restore_cache_line (¢ry, buf); if (gftp_fd_write (NULL, buf, strlen (buf), newfd) < 0) break; } } close (indexfd); close (newfd); unlink (oldindexfile); rename (newindexfile, oldindexfile); g_free (oldindexfile); g_free (newindexfile); }