Mercurial > gftp.yaz
view lib/cache.c @ 635:84fafa1b8ce8
* en_CA.po: Updated Canadian English translation.
author | adamw |
---|---|
date | Fri, 03 Dec 2004 19:05:14 +0000 |
parents | 7f54d0c0edbc |
children | d553d14a2565 |
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; time_t expiration_date; char *pos1, *pos2, *pos3; }; 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, _("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, _("Error: Invalid line %s in cache index file\n"), line); return (-1); } centry->pos2 = pos; *pos++ = '\0'; centry->server_type = strtol (pos, NULL, 10); if ((pos = strchr (pos, '\t')) == NULL || *(pos + 1) == '\0') { if (request != NULL) request->logging_function (gftp_logging_error, request, _("Error: Invalid line %s in cache index file\n"), line); return (-1); } centry->pos3 = pos; *pos++ = '\0'; centry->expiration_date = strtol (pos, NULL, 10); return (0); } static 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'; if (centry->pos3 != NULL) *centry->pos3 = '\t'; } void gftp_generate_cache_description (gftp_request * request, char *description, size_t len, int ignore_directory) { g_snprintf (description, len, "%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); } int gftp_new_cache_entry (gftp_request * request) { char *cachedir, *tempstr, *temp1str; int cache_fd, fd; intptr_t cache_ttl; ssize_t ret; time_t t; gftp_lookup_request_option (request, "cache_ttl", &cache_ttl); time (&t); t += cache_ttl; cachedir = gftp_expand_path (NULL, 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, _("Error: Could not make directory %s: %s\n"), cachedir, g_strerror (errno)); return (-1); } } tempstr = g_strdup_printf ("%s/index.db", cachedir); if ((fd = gftp_fd_open (request, tempstr, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { 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, _("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\t%ld\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, t); 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, _("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; time_t now; time (&now); gftp_generate_cache_description (request, description, sizeof (description), 0); indexfile = gftp_expand_path (NULL, BASE_CONF_DIR "/cache/index.db"); if ((indexfd = gftp_fd_open (NULL, indexfile, O_RDONLY, 0)) == -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; /* See if this entry is still valid... */ if (centry.expiration_date < now) continue; if (strcmp (description, centry.url) == 0) { if (close (indexfd) != 0) { if (request != NULL) request->logging_function (gftp_logging_error, request, _("Error closing file descriptor: %s\n"), g_strerror (errno)); return (-1); } if ((cachefd = gftp_fd_open (request, centry.file, O_RDONLY, 0)) == -1) 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, _("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 = gftp_expand_path (NULL, BASE_CONF_DIR "/cache/index.db"); if ((indexfd = gftp_fd_open (NULL, indexfile, O_RDONLY, 0)) == -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, char *descr, int ignore_directory) { char *oldindexfile, *newindexfile, buf[BUFSIZ], description[BUFSIZ]; int indexfd, newfd, del_entry; gftp_getline_buffer * rbuf; gftp_cache_entry centry; size_t len; time_t now; g_return_if_fail (request != NULL || descr != NULL); time (&now); if (request != NULL) { gftp_generate_cache_description (request, description, sizeof (description), ignore_directory); } else if (descr != NULL) { strncpy (description, descr, sizeof (description)); description[sizeof (description) - 1] = '\0'; } else return; oldindexfile = gftp_expand_path (NULL, BASE_CONF_DIR "/cache/index.db"); if ((indexfd = gftp_fd_open (NULL, oldindexfile, O_RDONLY, 0)) == -1) { g_free (oldindexfile); return; } newindexfile = gftp_expand_path (NULL, BASE_CONF_DIR "/cache/index.db.new"); if ((newfd = gftp_fd_open (request, newindexfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) { 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; del_entry = 0; if (centry.expiration_date < now) del_entry = 1; else if (ignore_directory) { if (strncmp (centry.url, description, strlen (description)) == 0) del_entry = 1; } else { if (strcmp (centry.url, description) == 0) del_entry = 1; } if (del_entry) unlink (centry.file); else { /* 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); /* 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 */ len = strlen (buf); buf[len--] = '\n'; if (gftp_fd_write (NULL, buf, len, newfd) < 0) break; } } close (indexfd); close (newfd); unlink (oldindexfile); rename (newindexfile, oldindexfile); g_free (oldindexfile); g_free (newindexfile); }