# HG changeset patch # User masneyb # Date 1036549225 0 # Node ID e5f6054590b59eae97a7ba43ee965ab1b528fff6 # Parent eec25f21577292df70fd144307d18595bd750742 2002-11-5 Brian Masney * lib/*.c src/gtk/*.c - removed function declarations for the static functions from the top of the file. I had to rearrange the order of a bunch of functions to avoid compiler warnings * lib/gftp.h - include sys/sysmacros.h. If major() and minor() isn't defined, give a compiler warning and define our own * lib/local.c (local_get_next_file) - if this file is a device, store the major/minor number in the file size * src/gtk/misc-gtk.c (add_file_listbox) - if this file is a device, use the major() and minor() macros to display the major and minor number diff -r eec25f215772 -r e5f6054590b5 lib/bookmark.c --- a/lib/bookmark.c Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/bookmark.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,47 +20,6 @@ #include "gftp.h" static const char cvsid[] = "$Id$"; -static int bookmark_parse_url ( gftp_request * request, - const char * url ); - -void -bookmark_init (gftp_request * request) -{ - g_return_if_fail (request != NULL); - - request->protonum = GFTP_BOOKMARK_NUM; - request->init = bookmark_init; - request->destroy = NULL; - request->connect = NULL; - request->disconnect = NULL; - request->get_file = NULL; - request->put_file = NULL; - request->transfer_file = NULL; - request->get_next_file_chunk = NULL; - request->put_next_file_chunk = NULL; - request->end_transfer = NULL; - request->list_files = NULL; - request->get_next_file = NULL; - request->set_data_type = NULL; - request->get_file_size = NULL; - request->chdir = NULL; - request->rmdir = NULL; - request->rmfile = NULL; - request->mkdir = NULL; - request->rename = NULL; - request->chmod = NULL; - request->set_file_time = NULL; - request->site = NULL; - request->parse_url = bookmark_parse_url; - request->url_prefix = "bookmark"; - request->protocol_name = "Bookmark"; - request->need_hostport = 0; - request->need_userpass = 0; - request->use_threads = 0; - request->use_cache = 0; - request->always_connected = 0; - gftp_set_config_options (request); -} static int bookmark_parse_url (gftp_request * request, const char * url) @@ -118,3 +77,43 @@ return (0); } + +void +bookmark_init (gftp_request * request) +{ + g_return_if_fail (request != NULL); + + request->protonum = GFTP_BOOKMARK_NUM; + request->init = bookmark_init; + request->destroy = NULL; + request->connect = NULL; + request->disconnect = NULL; + request->get_file = NULL; + request->put_file = NULL; + request->transfer_file = NULL; + request->get_next_file_chunk = NULL; + request->put_next_file_chunk = NULL; + request->end_transfer = NULL; + request->list_files = NULL; + request->get_next_file = NULL; + request->set_data_type = NULL; + request->get_file_size = NULL; + request->chdir = NULL; + request->rmdir = NULL; + request->rmfile = NULL; + request->mkdir = NULL; + request->rename = NULL; + request->chmod = NULL; + request->set_file_time = NULL; + request->site = NULL; + request->parse_url = bookmark_parse_url; + request->url_prefix = "bookmark"; + request->protocol_name = "Bookmark"; + request->need_hostport = 0; + request->need_userpass = 0; + request->use_threads = 0; + request->use_cache = 0; + request->always_connected = 0; + gftp_set_config_options (request); +} + diff -r eec25f215772 -r e5f6054590b5 lib/gftp.h --- a/lib/gftp.h Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/gftp.h Wed Nov 06 02:20:25 2002 +0000 @@ -35,6 +35,7 @@ #endif #include #include +#include #include #include #include @@ -76,6 +77,18 @@ #define AF_LOCAL AF_UNIX #endif +/* We need the major() and minor() macros in the user interface. If they aren't + defined by the system, we'll just define them here. */ +#ifndef major +#warning major macro was not defined by the system. Defining one that is probably wrong for your system +#define major(dev) (((dev) >> 8) & 0xff) +#endif + +#ifndef minor +#warning minor macro was not defined by the system. Defining one that is probably wrong for your system +#define minor(dev) ((dev) & 0xff) +#endif + #ifdef HAVE_DMALLOC #include #endif diff -r eec25f215772 -r e5f6054590b5 lib/local.c --- a/lib/local.c Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/local.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,51 +20,6 @@ #include "gftp.h" static const char cvsid[] = "$Id$"; -static void local_destroy ( gftp_request * request ); -static void local_remove_key ( gpointer key, - gpointer value, - gpointer user_data ); -static int local_connect ( gftp_request * request ); -static void local_disconnect ( gftp_request * request ); -static long local_get_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize ); -static int local_put_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize, - off_t totalsize ); -static int local_end_transfer ( gftp_request * request ); -static int local_get_next_file ( gftp_request * request, - gftp_file * fle, - FILE * fd ); -static int local_list_files ( gftp_request * request ); -static off_t local_get_file_size ( gftp_request * request, - const char *filename ); -static int local_chdir ( gftp_request * request, - const char *directory ); -static int local_rmdir ( gftp_request * request, - const char *directory ); -static int local_rmfile ( gftp_request * request, - const char *file ); -static int local_mkdir ( gftp_request * request, - const char *directory ); -static int local_rename ( gftp_request * request, - const char *oldname, - const char *newname ); -static int local_chmod ( gftp_request * request, - const char *file, - int mode ); -static int local_set_file_time ( gftp_request * request, - const char *file, - time_t datetime ); -static char *make_text_mode ( gftp_file * fle, - mode_t mode ); -static gint hash_compare ( gconstpointer path1, - gconstpointer path2 ); -static guint hash_function ( gconstpointer key ); - typedef struct local_protocol_data_tag { DIR *dir; @@ -72,51 +27,10 @@ } local_protocol_data; -void -local_init (gftp_request * request) +static void +local_remove_key (gpointer key, gpointer value, gpointer user_data) { - local_protocol_data *lpd; - - g_return_if_fail (request != NULL); - - request->protonum = GFTP_LOCAL_NUM; - request->init = local_init; - request->destroy = local_destroy; - request->connect = local_connect; - request->disconnect = local_disconnect; - request->get_file = local_get_file; - request->put_file = local_put_file; - request->transfer_file = NULL; - request->get_next_file_chunk = NULL; - request->put_next_file_chunk = NULL; - request->end_transfer = local_end_transfer; - request->abort_transfer = local_end_transfer; /* NOTE: uses end_transfer */ - request->list_files = local_list_files; - request->get_next_file = local_get_next_file; - request->set_data_type = NULL; - request->get_file_size = local_get_file_size; - request->chdir = local_chdir; - request->rmdir = local_rmdir; - request->rmfile = local_rmfile; - request->mkdir = local_mkdir; - request->rename = local_rename; - request->chmod = local_chmod; - request->set_file_time = local_set_file_time; - request->site = NULL; - request->parse_url = NULL; - request->url_prefix = "file"; - request->protocol_name = "Local"; - request->need_hostport = 0; - request->need_userpass = 0; - request->use_cache = 0; - request->use_threads = 0; - request->always_connected = 1; - gftp_set_config_options (request); - - lpd = g_malloc0 (sizeof (*lpd)); - request->protocol_data = lpd; - lpd->userhash = g_hash_table_new (hash_function, hash_compare); - lpd->grouphash = g_hash_table_new (hash_function, hash_compare); + g_free (value); } @@ -137,13 +51,6 @@ } -static void -local_remove_key (gpointer key, gpointer value, gpointer user_data) -{ - g_free (value); -} - - static int local_connect (gftp_request * request) { @@ -357,6 +264,92 @@ } +static char * +make_text_mode (gftp_file * fle, mode_t mode) +{ + char *str; + + str = g_malloc0 (11); + + str[0] = '?'; + if (S_ISREG (mode)) + str[0] = '-'; + + if (S_ISLNK (mode)) + { + fle->islink = 1; + str[0] = 'l'; + } + + if (S_ISBLK (mode)) + { + fle->isblock = 1; + str[0] = 'b'; + } + + if (S_ISCHR (mode)) + { + fle->ischar = 1; + str[0] = 'c'; + } + + if (S_ISFIFO (mode)) + { + fle->isfifo = 1; + str[0] = 'p'; + } + + if (S_ISSOCK (mode)) + { + fle->issocket = 1; + str[0] = 's'; + } + + if (S_ISDIR (mode)) + { + fle->isdir = 1; + str[0] = 'd'; + } + + str[1] = mode & S_IRUSR ? 'r' : '-'; + str[2] = mode & S_IWUSR ? 'w' : '-'; + + if ((mode & S_ISUID) && (mode & S_IXUSR)) + str[3] = 's'; + else if (mode & S_ISUID) + str[3] = 'S'; + else if (mode & S_IXUSR) + str[3] = 'x'; + else + str[3] = '-'; + + str[4] = mode & S_IRGRP ? 'r' : '-'; + str[5] = mode & S_IWGRP ? 'w' : '-'; + + if ((mode & S_ISGID) && (mode & S_IXGRP)) + str[6] = 's'; + else if (mode & S_ISGID) + str[6] = 'S'; + else if (mode & S_IXGRP) + str[6] = 'x'; + else + str[6] = '-'; + + str[7] = mode & S_IROTH ? 'r' : '-'; + str[8] = mode & S_IWOTH ? 'w' : '-'; + + if ((mode & S_ISVTX) && (mode & S_IXOTH)) + str[9] = 't'; + else if (mode & S_ISVTX) + str[9] = 'T'; + else if (mode & S_IXOTH) + str[9] = 'x'; + else + str[9] = '-'; + return (str); +} + + static int local_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd) { @@ -440,14 +433,7 @@ if ((fle->attribs[0] == 'b' || fle->attribs[0] == 'u' || fle->attribs[0] == 'c')) - { - /* FIXME find out if sys/sysmacros.h is portable, and if - #define {major,minor} is portable. If so, use that instead. If not, - I will have to add a configure flag to find out the size of the - major numbers */ - fle->size = ((((int) st.st_rdev) >> 8) & 0xFF) << 16; - fle->size |= st.st_rdev & 0xFF; - } + fle->size = (off_t) st.st_rdev; else fle->size = st.st_size; @@ -684,92 +670,6 @@ } -static char * -make_text_mode (gftp_file * fle, mode_t mode) -{ - char *str; - - str = g_malloc0 (11); - - str[0] = '?'; - if (S_ISREG (mode)) - str[0] = '-'; - - if (S_ISLNK (mode)) - { - fle->islink = 1; - str[0] = 'l'; - } - - if (S_ISBLK (mode)) - { - fle->isblock = 1; - str[0] = 'b'; - } - - if (S_ISCHR (mode)) - { - fle->ischar = 1; - str[0] = 'c'; - } - - if (S_ISFIFO (mode)) - { - fle->isfifo = 1; - str[0] = 'p'; - } - - if (S_ISSOCK (mode)) - { - fle->issocket = 1; - str[0] = 's'; - } - - if (S_ISDIR (mode)) - { - fle->isdir = 1; - str[0] = 'd'; - } - - str[1] = mode & S_IRUSR ? 'r' : '-'; - str[2] = mode & S_IWUSR ? 'w' : '-'; - - if ((mode & S_ISUID) && (mode & S_IXUSR)) - str[3] = 's'; - else if (mode & S_ISUID) - str[3] = 'S'; - else if (mode & S_IXUSR) - str[3] = 'x'; - else - str[3] = '-'; - - str[4] = mode & S_IRGRP ? 'r' : '-'; - str[5] = mode & S_IWGRP ? 'w' : '-'; - - if ((mode & S_ISGID) && (mode & S_IXGRP)) - str[6] = 's'; - else if (mode & S_ISGID) - str[6] = 'S'; - else if (mode & S_IXGRP) - str[6] = 'x'; - else - str[6] = '-'; - - str[7] = mode & S_IROTH ? 'r' : '-'; - str[8] = mode & S_IWOTH ? 'w' : '-'; - - if ((mode & S_ISVTX) && (mode & S_IXOTH)) - str[9] = 't'; - else if (mode & S_ISVTX) - str[9] = 'T'; - else if (mode & S_IXOTH) - str[9] = 'x'; - else - str[9] = '-'; - return (str); -} - - static gint hash_compare (gconstpointer path1, gconstpointer path2) { @@ -783,3 +683,51 @@ return (GPOINTER_TO_UINT (key)); } + +void +local_init (gftp_request * request) +{ + local_protocol_data *lpd; + + g_return_if_fail (request != NULL); + + request->protonum = GFTP_LOCAL_NUM; + request->init = local_init; + request->destroy = local_destroy; + request->connect = local_connect; + request->disconnect = local_disconnect; + request->get_file = local_get_file; + request->put_file = local_put_file; + request->transfer_file = NULL; + request->get_next_file_chunk = NULL; + request->put_next_file_chunk = NULL; + request->end_transfer = local_end_transfer; + request->abort_transfer = local_end_transfer; /* NOTE: uses end_transfer */ + request->list_files = local_list_files; + request->get_next_file = local_get_next_file; + request->set_data_type = NULL; + request->get_file_size = local_get_file_size; + request->chdir = local_chdir; + request->rmdir = local_rmdir; + request->rmfile = local_rmfile; + request->mkdir = local_mkdir; + request->rename = local_rename; + request->chmod = local_chmod; + request->set_file_time = local_set_file_time; + request->site = NULL; + request->parse_url = NULL; + request->url_prefix = "file"; + request->protocol_name = "Local"; + request->need_hostport = 0; + request->need_userpass = 0; + request->use_cache = 0; + request->use_threads = 0; + request->always_connected = 1; + gftp_set_config_options (request); + + lpd = g_malloc0 (sizeof (*lpd)); + request->protocol_data = lpd; + lpd->userhash = g_hash_table_new (hash_function, hash_compare); + lpd->grouphash = g_hash_table_new (hash_function, hash_compare); +} + diff -r eec25f215772 -r e5f6054590b5 lib/protocols.c --- a/lib/protocols.c Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/protocols.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,27 +20,6 @@ #include "gftp.h" static const char cvsid[] = "$Id$"; -static time_t parse_time ( char **str ); -static int gftp_parse_ls_eplf ( char *str, - gftp_file * fle ); -static int gftp_parse_ls_unix ( char *str, - int cols, - gftp_file * fle ); -static int gftp_parse_ls_nt ( char *str, - gftp_file * fle ); -static int gftp_parse_ls_novell ( char *str, - gftp_file * fle ); -static char *copy_token ( char **dest, - char *source ); -static char *goto_next_token ( char *pos ); -static GList * gftp_get_dir_listing ( gftp_transfer * transfer, - int getothdir ); -static GHashTable * gftp_gen_dir_hash ( gftp_request * request ); -static void gftp_destroy_dir_hash ( GHashTable * dirhash ); -static void destroy_hash_ent ( gpointer key, - gpointer value, - gpointer user_data ); - gftp_request * gftp_request_new (void) { @@ -1043,87 +1022,45 @@ } -int -gftp_parse_ls (const char *lsoutput, gftp_file * fle) +static char * +copy_token (char **dest, char *source) { - int result, cols; - char *str, *pos; - - g_return_val_if_fail (lsoutput != NULL, -2); - g_return_val_if_fail (fle != NULL, -2); - - str = g_malloc (strlen (lsoutput) + 1); - strcpy (str, lsoutput); - memset (fle, 0, sizeof (*fle)); + /* This function is used internally by gftp_parse_ls () */ + char *endpos, savepos; - if (str[strlen (str) - 1] == '\n') - str[strlen (str) - 1] = '\0'; - if (str[strlen (str) - 1] == '\r') - str[strlen (str) - 1] = '\0'; - if (*lsoutput == '+') /* EPLF format */ - result = gftp_parse_ls_eplf (str, fle); - else if (isdigit ((int) str[0]) && str[2] == '-') /* DOS/WinNT format */ - result = gftp_parse_ls_nt (str, fle); - else if (str[1] == ' ' && str[2] == '[') /* Novell format */ - result = gftp_parse_ls_novell (str, fle); - else - { - /* UNIX/MacOS format */ + endpos = source; + while (*endpos != ' ' && *endpos != '\t' && *endpos != '\0') + endpos++; + if (*endpos == '\0') + return (NULL); - /* If there is no space between the attribs and links field, just make one */ - if (strlen (str) > 10) - str[10] = ' '; + savepos = *endpos; + *endpos = '\0'; + *dest = g_malloc (endpos - source + 1); + strcpy (*dest, source); + *endpos = savepos; - /* Determine the number of columns */ - cols = 0; - pos = str; - while (*pos != '\0') - { - while (*pos != '\0' && *pos != ' ' && *pos != '\t') - { - if (*pos == ':') - break; - pos++; - } + /* Skip the blanks till we get to the next entry */ + source = endpos + 1; + while ((*source == ' ' || *source == '\t') && *source != '\0') + source++; + return (source); +} - cols++; - - if (*pos == ':') - { - cols++; - break; - } - - while (*pos == ' ' || *pos == '\t') - pos++; - } - if (cols > 6) - result = gftp_parse_ls_unix (str, cols, fle); - else - result = -2; - } - g_free (str); - - if (fle->attribs == NULL) - return (result); +static char * +goto_next_token (char *pos) +{ + while (*pos != ' ' && *pos != '\t' && *pos != '\0') + pos++; - if (*fle->attribs == 'd') - fle->isdir = 1; - if (*fle->attribs == 'l') - fle->islink = 1; - if (strchr (fle->attribs, 'x') != NULL && !fle->isdir && !fle->islink) - fle->isexe = 1; - if (*fle->attribs == 'b') - fle->isblock = 1; - if (*fle->attribs == 'c') - fle->ischar = 1; - if (*fle->attribs == 's') - fle->issocket = 1; - if (*fle->attribs == 'p') - fle->isfifo = 1; + if (pos == '\0') + return (pos); - return (result); + while ((*pos == ' ' || *pos == '\t') && *pos != '\0') + pos++; + + return (pos); } @@ -1456,45 +1393,138 @@ } -static char * -copy_token (char **dest, char *source) +int +gftp_parse_ls (const char *lsoutput, gftp_file * fle) { - /* This function is used internally by gftp_parse_ls () */ - char *endpos, savepos; + int result, cols; + char *str, *pos; + + g_return_val_if_fail (lsoutput != NULL, -2); + g_return_val_if_fail (fle != NULL, -2); + + str = g_malloc (strlen (lsoutput) + 1); + strcpy (str, lsoutput); + memset (fle, 0, sizeof (*fle)); - endpos = source; - while (*endpos != ' ' && *endpos != '\t' && *endpos != '\0') - endpos++; - if (*endpos == '\0') - return (NULL); + if (str[strlen (str) - 1] == '\n') + str[strlen (str) - 1] = '\0'; + if (str[strlen (str) - 1] == '\r') + str[strlen (str) - 1] = '\0'; + if (*lsoutput == '+') /* EPLF format */ + result = gftp_parse_ls_eplf (str, fle); + else if (isdigit ((int) str[0]) && str[2] == '-') /* DOS/WinNT format */ + result = gftp_parse_ls_nt (str, fle); + else if (str[1] == ' ' && str[2] == '[') /* Novell format */ + result = gftp_parse_ls_novell (str, fle); + else + { + /* UNIX/MacOS format */ + + /* If there is no space between the attribs and links field, just make one */ + if (strlen (str) > 10) + str[10] = ' '; - savepos = *endpos; - *endpos = '\0'; - *dest = g_malloc (endpos - source + 1); - strcpy (*dest, source); - *endpos = savepos; + /* Determine the number of columns */ + cols = 0; + pos = str; + while (*pos != '\0') + { + while (*pos != '\0' && *pos != ' ' && *pos != '\t') + { + if (*pos == ':') + break; + pos++; + } + + cols++; + + if (*pos == ':') + { + cols++; + break; + } + + while (*pos == ' ' || *pos == '\t') + pos++; + } - /* Skip the blanks till we get to the next entry */ - source = endpos + 1; - while ((*source == ' ' || *source == '\t') && *source != '\0') - source++; - return (source); + if (cols > 6) + result = gftp_parse_ls_unix (str, cols, fle); + else + result = -2; + } + g_free (str); + + if (fle->attribs == NULL) + return (result); + + if (*fle->attribs == 'd') + fle->isdir = 1; + if (*fle->attribs == 'l') + fle->islink = 1; + if (strchr (fle->attribs, 'x') != NULL && !fle->isdir && !fle->islink) + fle->isexe = 1; + if (*fle->attribs == 'b') + fle->isblock = 1; + if (*fle->attribs == 'c') + fle->ischar = 1; + if (*fle->attribs == 's') + fle->issocket = 1; + if (*fle->attribs == 'p') + fle->isfifo = 1; + + return (result); } -static char * -goto_next_token (char *pos) +static GHashTable * +gftp_gen_dir_hash (gftp_request * request) { - while (*pos != ' ' && *pos != '\t' && *pos != '\0') - pos++; + unsigned long *newsize; + GHashTable * dirhash; + gftp_file * fle; + char * newname; + - if (pos == '\0') - return (pos); + dirhash = g_hash_table_new (string_hash_function, string_hash_compare); + if (gftp_list_files (request) == 0) + { + fle = g_malloc0 (sizeof (*fle)); + while (gftp_get_next_file (request, NULL, fle) > 0) + { + newname = fle->file; + newsize = g_malloc (sizeof (unsigned long)); + *newsize = fle->size; + g_hash_table_insert (dirhash, newname, newsize); + fle->file = NULL; + gftp_file_destroy (fle); + } + gftp_end_transfer (request); + g_free (fle); + } + else + { + g_hash_table_destroy (dirhash); + dirhash = NULL; + } + return (dirhash); +} - while ((*pos == ' ' || *pos == '\t') && *pos != '\0') - pos++; + +static void +destroy_hash_ent (gpointer key, gpointer value, gpointer user_data) +{ - return (pos); + g_free (key); + g_free (value); +} + + +static void +gftp_destroy_dir_hash (GHashTable * dirhash) +{ + g_hash_table_foreach (dirhash, destroy_hash_ent, NULL); + g_hash_table_destroy (dirhash); } @@ -1663,57 +1693,6 @@ } -static GHashTable * -gftp_gen_dir_hash (gftp_request * request) -{ - unsigned long *newsize; - GHashTable * dirhash; - gftp_file * fle; - char * newname; - - - dirhash = g_hash_table_new (string_hash_function, string_hash_compare); - if (gftp_list_files (request) == 0) - { - fle = g_malloc0 (sizeof (*fle)); - while (gftp_get_next_file (request, NULL, fle) > 0) - { - newname = fle->file; - newsize = g_malloc (sizeof (unsigned long)); - *newsize = fle->size; - g_hash_table_insert (dirhash, newname, newsize); - fle->file = NULL; - gftp_file_destroy (fle); - } - gftp_end_transfer (request); - g_free (fle); - } - else - { - g_hash_table_destroy (dirhash); - dirhash = NULL; - } - return (dirhash); -} - - -static void -gftp_destroy_dir_hash (GHashTable * dirhash) -{ - g_hash_table_foreach (dirhash, destroy_hash_ent, NULL); - g_hash_table_destroy (dirhash); -} - - -static void -destroy_hash_ent (gpointer key, gpointer value, gpointer user_data) -{ - - g_free (key); - g_free (value); -} - - int gftp_get_file_transfer_mode (char *filename, int def) { diff -r eec25f215772 -r e5f6054590b5 lib/rfc2068.c --- a/lib/rfc2068.c Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/rfc2068.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,32 +20,6 @@ #include "gftp.h" static const char cvsid[] = "$Id$"; -static int rfc2068_connect ( gftp_request * request ); -static void rfc2068_disconnect ( gftp_request * request ); -static long rfc2068_get_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize ); -static size_t rfc2068_get_next_file_chunk ( gftp_request * request, - char *buf, - size_t size ); -static int rfc2068_end_transfer ( gftp_request * request ); -static int rfc2068_list_files ( gftp_request * request ); -static off_t rfc2068_get_file_size ( gftp_request * request, - const char *filename ); -static int rfc2068_get_next_file ( gftp_request * request, - gftp_file * fle, - FILE * fd ); -static int rfc2068_chdir ( gftp_request * request, - const char *directory ); -static unsigned long rfc2068_send_command ( gftp_request * request, - const char *command, - const char *extrahdr ); -static unsigned long rfc2068_read_response ( gftp_request * request ); -static int parse_html_line ( char *tempstr, - gftp_file * fle ); -static char *base64_encode ( char *str ); - typedef struct rfc2068_params_tag { unsigned long read_bytes, @@ -53,43 +27,185 @@ int chunked_transfer : 1; } rfc2068_params; -void -rfc2068_init (gftp_request * request) + +static char * +base64_encode (char *str) { - g_return_if_fail (request != NULL); + +/* The standard to Base64 encoding can be found in RFC2045 */ + + char *newstr, *newpos, *fillpos, *pos; + unsigned char table[64], encode[3]; + int i, num; + + for (i = 0; i < 26; i++) + { + table[i] = 'A' + i; + table[i + 26] = 'a' + i; + } + + for (i = 0; i < 10; i++) + table[i + 52] = '0' + i; + + table[62] = '+'; + table[63] = '-'; + + num = strlen (str) / 3; + if (strlen (str) % 3 > 0) + num++; + newstr = g_malloc (num * 4 + 1); + newstr[num * 4] = '\0'; + newpos = newstr; + + pos = str; + while (*pos != '\0') + { + memset (encode, 0, sizeof (encode)); + for (i = 0; i < 3 && *pos != '\0'; i++) + encode[i] = *pos++; + + fillpos = newpos; + *newpos++ = table[encode[0] >> 2]; + *newpos++ = table[(encode[0] & 3) << 4 | encode[1] >> 4]; + *newpos++ = table[(encode[1] & 0xF) << 2 | encode[2] >> 6]; + *newpos++ = table[encode[2] & 0x3F]; + while (i < 3) + fillpos[++i] = '='; + } + return (newstr); +} + + +static unsigned long +rfc2068_read_response (gftp_request * request) +{ + rfc2068_params * params; + char tempstr[255]; + + params = request->protocol_data; + params->max_bytes = 0; + + if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd)) + { + gftp_disconnect (request); + return (0); + } + + if (request->last_ftp_response) + g_free (request->last_ftp_response); + request->last_ftp_response = g_malloc (strlen (tempstr) + 1); + strcpy (request->last_ftp_response, tempstr); + + request->logging_function (gftp_logging_recv, request->user_data, "%s", + tempstr); + + params->chunked_transfer = 0; + while (1) + { + /* Read rest of proxy header */ + if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd)) + { + gftp_disconnect (request); + return (0); + } + + if (*tempstr == '\r' || *tempstr == '\n') + break; + + request->logging_function (gftp_logging_recv, request->user_data, "%s", + tempstr); - request->protonum = GFTP_HTTP_NUM; - request->init = rfc2068_init; - request->destroy = NULL; - request->connect = rfc2068_connect; - request->disconnect = rfc2068_disconnect; - request->get_file = rfc2068_get_file; - request->put_file = NULL; - request->transfer_file = NULL; - request->get_next_file_chunk = rfc2068_get_next_file_chunk; - request->put_next_file_chunk = NULL; - request->end_transfer = rfc2068_end_transfer; - request->abort_transfer = rfc2068_end_transfer; /* NOTE: uses end_transfer */ - request->list_files = rfc2068_list_files; - request->get_next_file = rfc2068_get_next_file; - request->set_data_type = NULL; - request->get_file_size = rfc2068_get_file_size; - request->chdir = rfc2068_chdir; - request->rmdir = NULL; - request->rmfile = NULL; - request->mkdir = NULL; - request->rename = NULL; - request->chmod = NULL; - request->site = NULL; - request->url_prefix = "http"; - request->protocol_name = "HTTP"; - request->need_hostport = 1; - request->need_userpass = 0; - request->use_cache = 1; - request->use_threads = 1; - request->always_connected = 0; - request->protocol_data = g_malloc0 (sizeof (rfc2068_params)); - gftp_set_config_options (request); + if (strncmp (tempstr, "Content-Length:", 15) == 0) + params->max_bytes = strtol (tempstr + 16, NULL, 10); + if (strncmp (tempstr, "Transfer-Encoding: chunked", 26) == 0) + params->chunked_transfer = 1; + } + + return (params->max_bytes); +} + + +static unsigned long +rfc2068_send_command (gftp_request * request, const char *command, + const char *extrahdr) +{ + char *tempstr, *str; + + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2); + g_return_val_if_fail (command != NULL, -2); + g_return_val_if_fail (request->sockfd_write != NULL, -2); + + request->logging_function (gftp_logging_send, request->user_data, "%s", + command); + + request->logging_function (gftp_logging_send, request->user_data, + "User-Agent: %s\n", version); + fprintf (request->sockfd_write, "%sUser-Agent: %s\nHost: %s\n", command, + version, request->hostname); + if (ferror (request->sockfd_write) != 0) + { + gftp_disconnect (request); + return (-2); + } + + if (request->use_proxy && request->proxy_username != NULL && + *request->proxy_username != '\0') + { + tempstr = g_strconcat (request->proxy_username, ":", + request->proxy_password, NULL); + str = base64_encode (tempstr); + g_free (tempstr); + + request->logging_function (gftp_logging_send, request->user_data, + "Proxy-authorization: Basic xxxx:xxxx\n"); + fprintf (request->sockfd_write, "Proxy-authorization: Basic %s\n", str); + g_free (str); + if (ferror (request->sockfd_write) != 0) + { + gftp_disconnect (request); + return (-2); + } + } + + if (request->username != NULL && *request->username != '\0') + { + tempstr = g_strconcat (request->username, ":", request->password, NULL); + str = base64_encode (tempstr); + g_free (tempstr); + + request->logging_function (gftp_logging_send, request->user_data, + "Authorization: Basic xxxx\n"); + fprintf (request->sockfd_write, "Authorization: Basic %s\n", str); + g_free (str); + if (ferror (request->sockfd_write) != 0) + { + gftp_disconnect (request); + return (-2); + } + } + + if (extrahdr) + { + request->logging_function (gftp_logging_send, request->user_data, + "%s", extrahdr); + request->logging_function (gftp_logging_send, request->user_data, "%s", + extrahdr); + fprintf (request->sockfd_write, "%s", extrahdr); + if (ferror (request->sockfd_write) != 0) + { + gftp_disconnect (request); + return (-2); + } + } + + fprintf (request->sockfd_write, "\n"); + if (ferror (request->sockfd_write) != 0) + { + gftp_disconnect (request); + return (-2); + } + return (rfc2068_read_response (request)); } @@ -406,223 +522,6 @@ static int -rfc2068_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd) -{ - rfc2068_params * params; - char tempstr[255]; - size_t len; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2); - g_return_val_if_fail (fle != NULL, -2); - - params = request->protocol_data; - if (request->last_dir_entry) - { - g_free (request->last_dir_entry); - request->last_dir_entry = NULL; - } - - while (1) - { - if (!gftp_fgets (request, tempstr, sizeof (tempstr), fd)) - { - gftp_file_destroy (fle); - return (-2); - } - - tempstr[sizeof (tempstr) - 1] = '\0'; - params->read_bytes += strlen (tempstr); - - if (params->chunked_transfer && strcmp (tempstr, "0\r\n") == 0) - { - while (gftp_fgets (request, tempstr, sizeof (tempstr), fd)) - { - if (strcmp (tempstr, "\r\n") == 0) - break; - } - gftp_file_destroy (fle); - return (0); - } - - if (parse_html_line (tempstr, fle) == 0 || fle->file == NULL) - gftp_file_destroy (fle); - else - break; - - if (params->max_bytes != 0 && params->read_bytes == params->max_bytes) - break; - } - - if (fle->file == NULL) - { - gftp_file_destroy (fle); - return (-2); - } - - len = strlen (tempstr); - if (!request->cached) - { - request->last_dir_entry = g_malloc (len + 1); - strcpy (request->last_dir_entry, tempstr); - request->last_dir_entry_len = len; - } - return (feof (fd) ? 0 : len); -} - - -static int -rfc2068_chdir (gftp_request * request, const char *directory) -{ - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2); - g_return_val_if_fail (directory != NULL, -2); - - if (request->directory != directory) - { - if (request->directory) - g_free (request->directory); - request->directory = g_malloc (strlen (directory) + 1); - strcpy (request->directory, directory); - } - return (0); -} - - -static unsigned long -rfc2068_send_command (gftp_request * request, const char *command, - const char *extrahdr) -{ - char *tempstr, *str; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2); - g_return_val_if_fail (command != NULL, -2); - g_return_val_if_fail (request->sockfd_write != NULL, -2); - - request->logging_function (gftp_logging_send, request->user_data, "%s", - command); - - request->logging_function (gftp_logging_send, request->user_data, - "User-Agent: %s\n", version); - fprintf (request->sockfd_write, "%sUser-Agent: %s\nHost: %s\n", command, - version, request->hostname); - if (ferror (request->sockfd_write) != 0) - { - gftp_disconnect (request); - return (-2); - } - - if (request->use_proxy && request->proxy_username != NULL && - *request->proxy_username != '\0') - { - tempstr = g_strconcat (request->proxy_username, ":", - request->proxy_password, NULL); - str = base64_encode (tempstr); - g_free (tempstr); - - request->logging_function (gftp_logging_send, request->user_data, - "Proxy-authorization: Basic xxxx:xxxx\n"); - fprintf (request->sockfd_write, "Proxy-authorization: Basic %s\n", str); - g_free (str); - if (ferror (request->sockfd_write) != 0) - { - gftp_disconnect (request); - return (-2); - } - } - - if (request->username != NULL && *request->username != '\0') - { - tempstr = g_strconcat (request->username, ":", request->password, NULL); - str = base64_encode (tempstr); - g_free (tempstr); - - request->logging_function (gftp_logging_send, request->user_data, - "Authorization: Basic xxxx\n"); - fprintf (request->sockfd_write, "Authorization: Basic %s\n", str); - g_free (str); - if (ferror (request->sockfd_write) != 0) - { - gftp_disconnect (request); - return (-2); - } - } - - if (extrahdr) - { - request->logging_function (gftp_logging_send, request->user_data, - "%s", extrahdr); - request->logging_function (gftp_logging_send, request->user_data, "%s", - extrahdr); - fprintf (request->sockfd_write, "%s", extrahdr); - if (ferror (request->sockfd_write) != 0) - { - gftp_disconnect (request); - return (-2); - } - } - - fprintf (request->sockfd_write, "\n"); - if (ferror (request->sockfd_write) != 0) - { - gftp_disconnect (request); - return (-2); - } - return (rfc2068_read_response (request)); -} - - -static unsigned long -rfc2068_read_response (gftp_request * request) -{ - rfc2068_params * params; - char tempstr[255]; - - params = request->protocol_data; - params->max_bytes = 0; - - if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd)) - { - gftp_disconnect (request); - return (0); - } - - if (request->last_ftp_response) - g_free (request->last_ftp_response); - request->last_ftp_response = g_malloc (strlen (tempstr) + 1); - strcpy (request->last_ftp_response, tempstr); - - request->logging_function (gftp_logging_recv, request->user_data, "%s", - tempstr); - - params->chunked_transfer = 0; - while (1) - { - /* Read rest of proxy header */ - if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd)) - { - gftp_disconnect (request); - return (0); - } - - if (*tempstr == '\r' || *tempstr == '\n') - break; - - request->logging_function (gftp_logging_recv, request->user_data, "%s", - tempstr); - - if (strncmp (tempstr, "Content-Length:", 15) == 0) - params->max_bytes = strtol (tempstr + 16, NULL, 10); - if (strncmp (tempstr, "Transfer-Encoding: chunked", 26) == 0) - params->chunked_transfer = 1; - } - - return (params->max_bytes); -} - - -static int parse_html_line (char *tempstr, gftp_file * fle) { char months[13][3] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", @@ -803,49 +702,126 @@ } -static char * -base64_encode (char *str) +static int +rfc2068_get_next_file (gftp_request * request, gftp_file * fle, FILE * fd) { + rfc2068_params * params; + char tempstr[255]; + size_t len; -/* The standard to Base64 encoding can be found in RFC2045 */ + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2); + g_return_val_if_fail (fle != NULL, -2); + + params = request->protocol_data; + if (request->last_dir_entry) + { + g_free (request->last_dir_entry); + request->last_dir_entry = NULL; + } + + while (1) + { + if (!gftp_fgets (request, tempstr, sizeof (tempstr), fd)) + { + gftp_file_destroy (fle); + return (-2); + } - char *newstr, *newpos, *fillpos, *pos; - unsigned char table[64], encode[3]; - int i, num; + tempstr[sizeof (tempstr) - 1] = '\0'; + params->read_bytes += strlen (tempstr); + + if (params->chunked_transfer && strcmp (tempstr, "0\r\n") == 0) + { + while (gftp_fgets (request, tempstr, sizeof (tempstr), fd)) + { + if (strcmp (tempstr, "\r\n") == 0) + break; + } + gftp_file_destroy (fle); + return (0); + } - for (i = 0; i < 26; i++) + if (parse_html_line (tempstr, fle) == 0 || fle->file == NULL) + gftp_file_destroy (fle); + else + break; + + if (params->max_bytes != 0 && params->read_bytes == params->max_bytes) + break; + } + + if (fle->file == NULL) { - table[i] = 'A' + i; - table[i + 26] = 'a' + i; + gftp_file_destroy (fle); + return (-2); } - for (i = 0; i < 10; i++) - table[i + 52] = '0' + i; + len = strlen (tempstr); + if (!request->cached) + { + request->last_dir_entry = g_malloc (len + 1); + strcpy (request->last_dir_entry, tempstr); + request->last_dir_entry_len = len; + } + return (feof (fd) ? 0 : len); +} - table[62] = '+'; - table[63] = '-'; - num = strlen (str) / 3; - if (strlen (str) % 3 > 0) - num++; - newstr = g_malloc (num * 4 + 1); - newstr[num * 4] = '\0'; - newpos = newstr; +static int +rfc2068_chdir (gftp_request * request, const char *directory) +{ + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_HTTP_NUM, -2); + g_return_val_if_fail (directory != NULL, -2); + + if (request->directory != directory) + { + if (request->directory) + g_free (request->directory); + request->directory = g_malloc (strlen (directory) + 1); + strcpy (request->directory, directory); + } + return (0); +} + + +void +rfc2068_init (gftp_request * request) +{ + g_return_if_fail (request != NULL); - pos = str; - while (*pos != '\0') - { - memset (encode, 0, sizeof (encode)); - for (i = 0; i < 3 && *pos != '\0'; i++) - encode[i] = *pos++; + request->protonum = GFTP_HTTP_NUM; + request->init = rfc2068_init; + request->destroy = NULL; + request->connect = rfc2068_connect; + request->disconnect = rfc2068_disconnect; + request->get_file = rfc2068_get_file; + request->put_file = NULL; + request->transfer_file = NULL; + request->get_next_file_chunk = rfc2068_get_next_file_chunk; + request->put_next_file_chunk = NULL; + request->end_transfer = rfc2068_end_transfer; + request->abort_transfer = rfc2068_end_transfer; /* NOTE: uses end_transfer */ + request->list_files = rfc2068_list_files; + request->get_next_file = rfc2068_get_next_file; + request->set_data_type = NULL; + request->get_file_size = rfc2068_get_file_size; + request->chdir = rfc2068_chdir; + request->rmdir = NULL; + request->rmfile = NULL; + request->mkdir = NULL; + request->rename = NULL; + request->chmod = NULL; + request->site = NULL; + request->url_prefix = "http"; + request->protocol_name = "HTTP"; + request->need_hostport = 1; + request->need_userpass = 0; + request->use_cache = 1; + request->use_threads = 1; + request->always_connected = 0; + request->protocol_data = g_malloc0 (sizeof (rfc2068_params)); + gftp_set_config_options (request); +} - fillpos = newpos; - *newpos++ = table[encode[0] >> 2]; - *newpos++ = table[(encode[0] & 3) << 4 | encode[1] >> 4]; - *newpos++ = table[(encode[1] & 0xF) << 2 | encode[2] >> 6]; - *newpos++ = table[encode[2] & 0x3F]; - while (i < 3) - fillpos[++i] = '='; - } - return (newstr); -} diff -r eec25f215772 -r e5f6054590b5 lib/rfc959.c --- a/lib/rfc959.c Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/rfc959.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,91 +20,243 @@ #include "gftp.h" static const char cvsid[] = "$Id$"; -static int rfc959_connect ( gftp_request * request ); -static void rfc959_disconnect ( gftp_request * request ); -static long rfc959_get_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize ); -static int rfc959_put_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize, - off_t totalsize ); -static long rfc959_transfer_file ( gftp_request *fromreq, - const char *fromfile, - off_t fromsize, - gftp_request *toreq, - const char *tofile, - off_t tosize ); -static int rfc959_end_transfer ( gftp_request * request ); -static int rfc959_abort_transfer ( gftp_request * request ); -static int rfc959_list_files ( gftp_request * request ); -static int rfc959_set_data_type ( gftp_request * request, - int data_type ); -static off_t rfc959_get_file_size ( gftp_request * request, - const char *filename ); -static int rfc959_data_connection_new ( gftp_request * request ); -static int rfc959_accept_active_connection ( gftp_request * request ); -static int rfc959_send_command ( gftp_request * request, - const char *command ); -static int rfc959_read_response ( gftp_request * request ); -static int rfc959_chdir ( gftp_request * request, - const char *directory ); -static int rfc959_rmdir ( gftp_request * request, - const char *directory ); -static int rfc959_rmfile ( gftp_request * request, - const char *file ); -static int rfc959_mkdir ( gftp_request * request, - const char *directory ); -static int rfc959_rename ( gftp_request * request, - const char *oldname, - const char *newname ); -static int rfc959_chmod ( gftp_request * request, - const char *file, - int mode ); -static int rfc959_site ( gftp_request * request, - const char *command ); -static char *parse_ftp_proxy_string ( gftp_request * request ); +static int +rfc959_read_response (gftp_request * request) +{ + char tempstr[255], code[4]; + + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); + g_return_val_if_fail (request->sockfd != NULL, -2); + + *code = '\0'; + if (request->last_ftp_response) + { + g_free (request->last_ftp_response); + request->last_ftp_response = NULL; + } + + do + { + if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd)) + break; + tempstr[strlen (tempstr) - 1] = '\0'; + if (tempstr[strlen (tempstr) - 1] == '\r') + tempstr[strlen (tempstr) - 1] = '\0'; + if (isdigit ((int) *tempstr) && isdigit ((int) *(tempstr + 1)) + && isdigit ((int) *(tempstr + 2))) + { + strncpy (code, tempstr, 3); + code[3] = ' '; + } + request->logging_function (gftp_logging_recv, request->user_data, + "%s\n", tempstr); + } + while (strncmp (code, tempstr, 4) != 0); + + if (ferror (request->sockfd)) + { + request->logging_function (gftp_logging_send, request->user_data, + "Error reading from socket: %s\n", + g_strerror (errno)); + gftp_disconnect (request); + return (-1); + } + + request->last_ftp_response = g_malloc (strlen (tempstr) + 1); + strcpy (request->last_ftp_response, tempstr); + + if (request->last_ftp_response[0] == '4' && + request->last_ftp_response[1] == '2') + gftp_disconnect (request); + + return (*request->last_ftp_response); +} + + +static int +rfc959_send_command (gftp_request * request, const char *command) +{ + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); + g_return_val_if_fail (command != NULL, -2); + g_return_val_if_fail (request->sockfd != NULL, -2); + + if (strncmp (command, "PASS", 4) == 0) + { + request->logging_function (gftp_logging_send, request->user_data, + "PASS xxxx\n"); + } + else if (strncmp (command, "ACCT", 4) == 0) + { + request->logging_function (gftp_logging_send, request->user_data, + "ACCT xxxx\n"); + } + else + { + request->logging_function (gftp_logging_send, request->user_data, "%s", + command); + } + + if (gftp_fwrite (request, command, strlen (command), + request->sockfd_write) < 0) + return (-1); + + return (rfc959_read_response (request)); +} + + +static char * +parse_ftp_proxy_string (gftp_request * request) +{ + char *startpos, *endpos, *oldstr, *newstr, *newval, *tempport; + + g_return_val_if_fail (request != NULL, NULL); + g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, NULL); -void -rfc959_init (gftp_request * request) -{ - g_return_if_fail (request != NULL); + newstr = g_malloc (1); + *newstr = '\0'; + startpos = endpos = request->proxy_config; + while (*endpos != '\0') + { + tempport = NULL; + if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'p') + { + switch (tolower ((int) *(endpos + 2))) + { + case 'u': + newval = request->proxy_username; + break; + case 'p': + newval = request->proxy_password; + break; + case 'h': + newval = request->proxy_hostname; + break; + case 'o': + tempport = g_strdup_printf ("%d", request->proxy_port); + newval = tempport; + break; + case 'a': + newval = request->proxy_account; + break; + default: + endpos++; + continue; + } + } + else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'h') + { + switch (tolower ((int) *(endpos + 2))) + { + case 'u': + newval = request->username; + break; + case 'p': + newval = request->password; + break; + case 'h': + newval = request->hostname; + break; + case 'o': + tempport = g_strdup_printf ("%d", request->port); + newval = tempport; + break; + case 'a': + newval = request->account; + break; + default: + endpos++; + continue; + } + } + else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'n') + { + *endpos = '\0'; + oldstr = newstr; + newstr = g_strconcat (oldstr, startpos, "\r\n", NULL); + g_free (oldstr); + endpos += 2; + startpos = endpos; + continue; + } + else + { + endpos++; + continue; + } - request->protonum = GFTP_FTP_NUM; - request->init = rfc959_init; - request->destroy = NULL; - request->connect = rfc959_connect; - request->disconnect = rfc959_disconnect; - request->get_file = rfc959_get_file; - request->put_file = rfc959_put_file; - request->transfer_file = rfc959_transfer_file; - request->get_next_file_chunk = NULL; - request->put_next_file_chunk = NULL; - request->end_transfer = rfc959_end_transfer; - request->abort_transfer = rfc959_abort_transfer; - request->list_files = rfc959_list_files; - request->get_next_file = rfc959_get_next_file; - request->set_data_type = rfc959_set_data_type; - request->get_file_size = rfc959_get_file_size; - request->chdir = rfc959_chdir; - request->rmdir = rfc959_rmdir; - request->rmfile = rfc959_rmfile; - request->mkdir = rfc959_mkdir; - request->rename = rfc959_rename; - request->chmod = rfc959_chmod; - request->set_file_time = NULL; - request->site = rfc959_site; - request->parse_url = NULL; - request->url_prefix = "ftp"; - request->protocol_name = "FTP"; - request->need_hostport = 1; - request->need_userpass = 1; - request->use_cache = 1; - request->use_threads = 1; - request->always_connected = 0; - gftp_set_config_options (request); + *endpos = '\0'; + oldstr = newstr; + if (!newval) + newstr = g_strconcat (oldstr, startpos, NULL); + else + newstr = g_strconcat (oldstr, startpos, newval, NULL); + if (tempport) + { + g_free (tempport); + tempport = NULL; + } + g_free (oldstr); + endpos += 3; + startpos = endpos; + } + return (newstr); +} + + +static int +rfc959_chdir (gftp_request * request, const char *directory) +{ + char ret, *tempstr, *dir; + + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); + g_return_val_if_fail (directory != NULL, -2); + + if (strcmp (directory, "..") == 0) + ret = rfc959_send_command (request, "CDUP\r\n"); + else + { + tempstr = g_strconcat ("CWD ", directory, "\r\n", NULL); + ret = rfc959_send_command (request, tempstr); + g_free (tempstr); + } + + if (ret != '2') + return (-2); + + if (directory != request->directory) + { + if (request->directory) + { + g_free (request->directory); + request->directory = NULL; + } + + if (rfc959_send_command (request, "PWD\r\n") != '2') + return (-2); + + tempstr = strchr (request->last_ftp_response, '"'); + if (tempstr != NULL) + dir = tempstr + 1; + else + return (-2); + + tempstr = strchr (dir, '"'); + if (tempstr != NULL) + *tempstr = '\0'; + else + { + gftp_disconnect (request); + return (-2); + } + + request->directory = g_malloc (strlen (dir) + 1); + strcpy (request->directory, dir); + } + + return (0); } @@ -286,6 +438,166 @@ } +static int +rfc959_data_connection_new (gftp_request * request) +{ + char *pos, *pos1, resp, *command; + struct sockaddr_in data_addr; + size_t data_addr_len; + unsigned int temp[6]; + unsigned char ad[6]; + int i, sock; + + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); + g_return_val_if_fail (request->sockfd != NULL, -2); + + if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Failed to create a socket: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + return (-1); + } + + data_addr_len = sizeof (data_addr); + memset (&data_addr, 0, data_addr_len); + data_addr.sin_family = AF_INET; + + if (request->transfer_type == gftp_transfer_passive) + { + if ((resp = rfc959_send_command (request, "PASV\r\n")) != '2') + { + if (request->sockfd == NULL) + return (-2); + + request->transfer_type = gftp_transfer_active; + return (rfc959_data_connection_new (request)); + } + pos = request->last_ftp_response + 4; + while (!isdigit ((int) *pos) && *pos != '\0') + pos++; + if (*pos == '\0') + { + gftp_disconnect (request); + close (sock); + return (-2); + } + if (sscanf (pos, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2], + &temp[3], &temp[4], &temp[5]) != 6) + { + gftp_disconnect (request); + close (sock); + return (-2); + } + for (i = 0; i < 6; i++) + ad[i] = (unsigned char) (temp[i] & 0xff); + + memcpy (&data_addr.sin_addr, &ad[0], 4); + memcpy (&data_addr.sin_port, &ad[4], 2); + if (connect (sock, (struct sockaddr *) &data_addr, data_addr_len) == -1) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot create a data connection: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + close (sock); + return (-1); + } + } + else + { + getsockname (fileno (request->sockfd), (struct sockaddr *) &data_addr, + &data_addr_len); + data_addr.sin_port = 0; + if (bind (sock, (struct sockaddr *) &data_addr, data_addr_len) == -1) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot bind a port: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + close (sock); + return (-1); + } + + getsockname (sock, (struct sockaddr *) &data_addr, &data_addr_len); + if (listen (sock, 1) == -1) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot listen on port %d: %s\n"), + ntohs (data_addr.sin_port), + g_strerror (errno)); + gftp_disconnect (request); + close (sock); + return (-1); + } + pos = (char *) &data_addr.sin_addr; + pos1 = (char *) &data_addr.sin_port; + command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n", + pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff, + pos[3] & 0xff, pos1[0] & 0xff, + pos1[1] & 0xff); + resp = rfc959_send_command (request, command); + g_free (command); + if (resp != '2') + { + gftp_disconnect (request); + close (sock); + return (-2); + } + } + + if ((request->datafd = fdopen (sock, "rb+")) == NULL) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot fdopen() socket: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + return (-2); + } + + return (0); +} + + +static int +rfc959_accept_active_connection (gftp_request * request) +{ + struct sockaddr_in cli_addr; + size_t cli_addr_len; + int infd; + + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); + g_return_val_if_fail (request->datafd != NULL, -2); + g_return_val_if_fail (request->transfer_type == gftp_transfer_active, -2); + + cli_addr_len = sizeof (cli_addr); + if ((infd = accept (fileno (request->datafd), (struct sockaddr *) &cli_addr, + &cli_addr_len)) == -1) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot accept connection from server: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + return (-1); + } + + fclose (request->datafd); + + if ((request->datafd = fdopen (infd, "rb+")) == NULL) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Cannot fdopen() socket: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + return (-2); + } + return (0); +} + + static long rfc959_get_file (gftp_request * request, const char *filename, FILE * fd, off_t startsize) @@ -659,307 +971,6 @@ static int -rfc959_data_connection_new (gftp_request * request) -{ - char *pos, *pos1, resp, *command; - struct sockaddr_in data_addr; - size_t data_addr_len; - unsigned int temp[6]; - unsigned char ad[6]; - int i, sock; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); - g_return_val_if_fail (request->sockfd != NULL, -2); - - if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Failed to create a socket: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - return (-1); - } - - data_addr_len = sizeof (data_addr); - memset (&data_addr, 0, data_addr_len); - data_addr.sin_family = AF_INET; - - if (request->transfer_type == gftp_transfer_passive) - { - if ((resp = rfc959_send_command (request, "PASV\r\n")) != '2') - { - if (request->sockfd == NULL) - return (-2); - - request->transfer_type = gftp_transfer_active; - return (rfc959_data_connection_new (request)); - } - pos = request->last_ftp_response + 4; - while (!isdigit ((int) *pos) && *pos != '\0') - pos++; - if (*pos == '\0') - { - gftp_disconnect (request); - close (sock); - return (-2); - } - if (sscanf (pos, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2], - &temp[3], &temp[4], &temp[5]) != 6) - { - gftp_disconnect (request); - close (sock); - return (-2); - } - for (i = 0; i < 6; i++) - ad[i] = (unsigned char) (temp[i] & 0xff); - - memcpy (&data_addr.sin_addr, &ad[0], 4); - memcpy (&data_addr.sin_port, &ad[4], 2); - if (connect (sock, (struct sockaddr *) &data_addr, data_addr_len) == -1) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot create a data connection: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - close (sock); - return (-1); - } - } - else - { - getsockname (fileno (request->sockfd), (struct sockaddr *) &data_addr, - &data_addr_len); - data_addr.sin_port = 0; - if (bind (sock, (struct sockaddr *) &data_addr, data_addr_len) == -1) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot bind a port: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - close (sock); - return (-1); - } - - getsockname (sock, (struct sockaddr *) &data_addr, &data_addr_len); - if (listen (sock, 1) == -1) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot listen on port %d: %s\n"), - ntohs (data_addr.sin_port), - g_strerror (errno)); - gftp_disconnect (request); - close (sock); - return (-1); - } - pos = (char *) &data_addr.sin_addr; - pos1 = (char *) &data_addr.sin_port; - command = g_strdup_printf ("PORT %u,%u,%u,%u,%u,%u\r\n", - pos[0] & 0xff, pos[1] & 0xff, pos[2] & 0xff, - pos[3] & 0xff, pos1[0] & 0xff, - pos1[1] & 0xff); - resp = rfc959_send_command (request, command); - g_free (command); - if (resp != '2') - { - gftp_disconnect (request); - close (sock); - return (-2); - } - } - - if ((request->datafd = fdopen (sock, "rb+")) == NULL) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot fdopen() socket: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - return (-2); - } - - return (0); -} - - -static int -rfc959_accept_active_connection (gftp_request * request) -{ - struct sockaddr_in cli_addr; - size_t cli_addr_len; - int infd; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); - g_return_val_if_fail (request->datafd != NULL, -2); - g_return_val_if_fail (request->transfer_type == gftp_transfer_active, -2); - - cli_addr_len = sizeof (cli_addr); - if ((infd = accept (fileno (request->datafd), (struct sockaddr *) &cli_addr, - &cli_addr_len)) == -1) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot accept connection from server: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - return (-1); - } - - fclose (request->datafd); - - if ((request->datafd = fdopen (infd, "rb+")) == NULL) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Cannot fdopen() socket: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - return (-2); - } - return (0); -} - - -static int -rfc959_send_command (gftp_request * request, const char *command) -{ - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); - g_return_val_if_fail (command != NULL, -2); - g_return_val_if_fail (request->sockfd != NULL, -2); - - if (strncmp (command, "PASS", 4) == 0) - { - request->logging_function (gftp_logging_send, request->user_data, - "PASS xxxx\n"); - } - else if (strncmp (command, "ACCT", 4) == 0) - { - request->logging_function (gftp_logging_send, request->user_data, - "ACCT xxxx\n"); - } - else - { - request->logging_function (gftp_logging_send, request->user_data, "%s", - command); - } - - if (gftp_fwrite (request, command, strlen (command), - request->sockfd_write) < 0) - return (-1); - - return (rfc959_read_response (request)); -} - - -static int -rfc959_read_response (gftp_request * request) -{ - char tempstr[255], code[4]; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); - g_return_val_if_fail (request->sockfd != NULL, -2); - - *code = '\0'; - if (request->last_ftp_response) - { - g_free (request->last_ftp_response); - request->last_ftp_response = NULL; - } - - do - { - if (!gftp_fgets (request, tempstr, sizeof (tempstr), request->sockfd)) - break; - tempstr[strlen (tempstr) - 1] = '\0'; - if (tempstr[strlen (tempstr) - 1] == '\r') - tempstr[strlen (tempstr) - 1] = '\0'; - if (isdigit ((int) *tempstr) && isdigit ((int) *(tempstr + 1)) - && isdigit ((int) *(tempstr + 2))) - { - strncpy (code, tempstr, 3); - code[3] = ' '; - } - request->logging_function (gftp_logging_recv, request->user_data, - "%s\n", tempstr); - } - while (strncmp (code, tempstr, 4) != 0); - - if (ferror (request->sockfd)) - { - request->logging_function (gftp_logging_send, request->user_data, - "Error reading from socket: %s\n", - g_strerror (errno)); - gftp_disconnect (request); - return (-1); - } - - request->last_ftp_response = g_malloc (strlen (tempstr) + 1); - strcpy (request->last_ftp_response, tempstr); - - if (request->last_ftp_response[0] == '4' && - request->last_ftp_response[1] == '2') - gftp_disconnect (request); - - return (*request->last_ftp_response); -} - - -static int -rfc959_chdir (gftp_request * request, const char *directory) -{ - char ret, *tempstr, *dir; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, -2); - g_return_val_if_fail (directory != NULL, -2); - - if (strcmp (directory, "..") == 0) - ret = rfc959_send_command (request, "CDUP\r\n"); - else - { - tempstr = g_strconcat ("CWD ", directory, "\r\n", NULL); - ret = rfc959_send_command (request, tempstr); - g_free (tempstr); - } - - if (ret != '2') - return (-2); - - if (directory != request->directory) - { - if (request->directory) - { - g_free (request->directory); - request->directory = NULL; - } - - if (rfc959_send_command (request, "PWD\r\n") != '2') - return (-2); - - tempstr = strchr (request->last_ftp_response, '"'); - if (tempstr != NULL) - dir = tempstr + 1; - else - return (-2); - - tempstr = strchr (dir, '"'); - if (tempstr != NULL) - *tempstr = '\0'; - else - { - gftp_disconnect (request); - return (-2); - } - - request->directory = g_malloc (strlen (dir) + 1); - strcpy (request->directory, dir); - } - - return (0); -} - - -static int rfc959_rmdir (gftp_request * request, const char *directory) { char *tempstr, ret; @@ -1070,101 +1081,43 @@ } -static char * -parse_ftp_proxy_string (gftp_request * request) +void +rfc959_init (gftp_request * request) { - char *startpos, *endpos, *oldstr, *newstr, *newval, *tempport; - - g_return_val_if_fail (request != NULL, NULL); - g_return_val_if_fail (request->protonum == GFTP_FTP_NUM, NULL); + g_return_if_fail (request != NULL); - newstr = g_malloc (1); - *newstr = '\0'; - startpos = endpos = request->proxy_config; - while (*endpos != '\0') - { - tempport = NULL; - if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'p') - { - switch (tolower ((int) *(endpos + 2))) - { - case 'u': - newval = request->proxy_username; - break; - case 'p': - newval = request->proxy_password; - break; - case 'h': - newval = request->proxy_hostname; - break; - case 'o': - tempport = g_strdup_printf ("%d", request->proxy_port); - newval = tempport; - break; - case 'a': - newval = request->proxy_account; - break; - default: - endpos++; - continue; - } - } - else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'h') - { - switch (tolower ((int) *(endpos + 2))) - { - case 'u': - newval = request->username; - break; - case 'p': - newval = request->password; - break; - case 'h': - newval = request->hostname; - break; - case 'o': - tempport = g_strdup_printf ("%d", request->port); - newval = tempport; - break; - case 'a': - newval = request->account; - break; - default: - endpos++; - continue; - } - } - else if (*endpos == '%' && tolower ((int) *(endpos + 1)) == 'n') - { - *endpos = '\0'; - oldstr = newstr; - newstr = g_strconcat (oldstr, startpos, "\r\n", NULL); - g_free (oldstr); - endpos += 2; - startpos = endpos; - continue; - } - else - { - endpos++; - continue; - } - - *endpos = '\0'; - oldstr = newstr; - if (!newval) - newstr = g_strconcat (oldstr, startpos, NULL); - else - newstr = g_strconcat (oldstr, startpos, newval, NULL); - if (tempport) - { - g_free (tempport); - tempport = NULL; - } - g_free (oldstr); - endpos += 3; - startpos = endpos; - } - return (newstr); + request->protonum = GFTP_FTP_NUM; + request->init = rfc959_init; + request->destroy = NULL; + request->connect = rfc959_connect; + request->disconnect = rfc959_disconnect; + request->get_file = rfc959_get_file; + request->put_file = rfc959_put_file; + request->transfer_file = rfc959_transfer_file; + request->get_next_file_chunk = NULL; + request->put_next_file_chunk = NULL; + request->end_transfer = rfc959_end_transfer; + request->abort_transfer = rfc959_abort_transfer; + request->list_files = rfc959_list_files; + request->get_next_file = rfc959_get_next_file; + request->set_data_type = rfc959_set_data_type; + request->get_file_size = rfc959_get_file_size; + request->chdir = rfc959_chdir; + request->rmdir = rfc959_rmdir; + request->rmfile = rfc959_rmfile; + request->mkdir = rfc959_mkdir; + request->rename = rfc959_rename; + request->chmod = rfc959_chmod; + request->set_file_time = NULL; + request->site = rfc959_site; + request->parse_url = NULL; + request->url_prefix = "ftp"; + request->protocol_name = "FTP"; + request->need_hostport = 1; + request->need_userpass = 1; + request->use_cache = 1; + request->use_threads = 1; + request->always_connected = 0; + gftp_set_config_options (request); } diff -r eec25f215772 -r e5f6054590b5 lib/ssh.c --- a/lib/ssh.c Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/ssh.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,6 +20,10 @@ /* This will use Brian Wellington 's sftpserv program */ /* on the remote. Some of this code is derived from the sftp client */ +/* 11/5/2002 - This protocol is now obsolete by the SSH2 protocol. I'm not + going to be adding any new features to it, but I'll keep it inside the code + for a little bit. I do plan on removing it completely though */ + #include "gftp.h" static const char cvsid[] = "$Id$"; @@ -63,105 +67,217 @@ } ssh_message; -static void ssh_destroy ( gftp_request * request ); -static int ssh_connect ( gftp_request * request ); -static void ssh_disconnect ( gftp_request * request ); -static long ssh_get_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize ); -static int ssh_put_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize, - off_t totalsize ); -static size_t ssh_get_next_file_chunk ( gftp_request * request, - char *buf, - size_t size ); -static size_t ssh_put_next_file_chunk ( gftp_request * request, - char *buf, - size_t size ); -static int ssh_end_transfer ( gftp_request * request ); -static int ssh_list_files ( gftp_request * request ); -static int ssh_get_next_file ( gftp_request * request, - gftp_file * fle, - FILE * fd ); -static int ssh_chdir ( gftp_request * request, - const char *directory ); -static char *ssh_exec ( gftp_request * request, - const char *command, - size_t len); -static int ssh_rmdir ( gftp_request * request, - const char *directory ); -static int ssh_rmfile ( gftp_request * request, - const char *file ); -static int ssh_mkdir ( gftp_request * request, - const char *newdir ); -static int ssh_rename ( gftp_request * request, - const char *oldname, - const char *newname ); -static int ssh_chmod ( gftp_request * request, - const char *file, - int mode ); -static int ssh_send_command ( gftp_request * request, - int cmdnum, - const char *command, - size_t len ); -static int ssh_read_response ( gftp_request * request, - ssh_message *message, - FILE * fd ); -static char *ssh_read_message ( gftp_request * request, - char *buf, - size_t len, - FILE * fd ); -static char *ssh_read_line ( gftp_request * request ); -static void ssh_log_command ( gftp_request * request, - int channel, - int cmdnum, - const char *command, - size_t len, - int direction ); -static size_t ssh_remove_spaces ( char *string ); +static void +ssh_log_command (gftp_request * request, int channel, int cmdnum, + const char *command, size_t len, int direction) +{ + const char *pos; + char *tempstr; + int ok; + + switch (cmdnum) + { + case CHDIR: + tempstr = "CHDIR "; + break; + case GETDIR: + tempstr = "GETDIR "; + break; + case TELLDIR: + tempstr = "TELLDIR "; + break; + case SENDFILE: + tempstr = "SENDFILE "; + break; + case FILESIZE: + tempstr = "FILESIZE "; + break; + case FILEMODE: + tempstr = "FILEMODE "; + break; + case ENDDATA: + tempstr = "ENDDATA "; + break; + case FILEOK: + tempstr = "FILEOK "; + break; + case STREAM: + tempstr = "STREAM "; + break; + case REQUEST: + tempstr = "REQUEST "; + break; + case FILENAME: + tempstr = "FILENAME "; + break; + case EXEC: + tempstr = "EXEC "; + break; + case SKIPBYTES: + tempstr = "SKIPBYTES "; + break; + case ERROR: + tempstr = "ERROR: "; + break; + case SUCCESS: + tempstr = "SUCCESS "; + break; + case CLOSE: + tempstr = "CLOSE "; + break; + case SSH_VERSION: + tempstr = "VERSION "; + break; + case CANCEL: + tempstr = "CANCEL "; + break; + case FILETIME: + tempstr = "FILETIME "; + break; + default: + return; + } + + ok = 0; + if (command) + { + for (pos = command; pos < command + len; pos++) + { + if (*pos == '\0') + { + ok = 1; + break; + } + } + } + + request->logging_function (direction == GFTP_DIRECTION_DOWNLOAD ? + gftp_logging_send : gftp_logging_recv, + request->user_data, "%d: %s %s\n", channel, + tempstr, ok ? command : ""); +} + + +static int +ssh_send_command (gftp_request * request, int cmdnum, const char *command, + size_t len) +{ + ssh_parms * params; + char *buf; + int clen; -void -ssh_init (gftp_request * request) + params = request->protocol_data; + clen = htonl (len); + buf = g_malloc (len + 6); + buf[0] = params->channel; + buf[1] = cmdnum; + memcpy (&buf[2], &clen, 4); + if (command) + memcpy (&buf[6], command, len); + ssh_log_command (request, params->channel, cmdnum, command, len, 1); + + if (gftp_fwrite (request, buf, len + 6, request->sockfd_write) < 0) + return (-2); + + return 0; + +} + + +static char * +ssh_read_message (gftp_request * request, char *buf, size_t len, FILE * fd) { - g_return_if_fail (request != NULL); + if (fd == NULL) + fd = request->sockfd; + + fread (buf, len, 1, fd); + if (ferror (fd)) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Error: Could not read from socket: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + return (NULL); + } + + return (buf); +} + + +static int +ssh_read_response (gftp_request * request, ssh_message *message, FILE * fd) +{ + char buf[6]; + + if (ssh_read_message (request, buf, 6, fd) == NULL) + return (-1); - request->protonum = GFTP_SSH_NUM; - request->init = ssh_init; - request->destroy = ssh_destroy; - request->connect = ssh_connect; - request->disconnect = ssh_disconnect; - request->get_file = ssh_get_file; - request->put_file = ssh_put_file; - request->transfer_file = NULL; - request->get_next_file_chunk = ssh_get_next_file_chunk; - request->put_next_file_chunk = ssh_put_next_file_chunk; - request->end_transfer = ssh_end_transfer; - request->abort_transfer = NULL; /* FIXME */ - request->list_files = ssh_list_files; - request->get_next_file = ssh_get_next_file; - request->set_data_type = NULL; - request->get_file_size = NULL; - request->chdir = ssh_chdir; - request->rmdir = ssh_rmdir; - request->rmfile = ssh_rmfile; - request->mkdir = ssh_mkdir; - request->rename = ssh_rename; - request->chmod = ssh_chmod; - request->set_file_time = NULL; - request->site = NULL; - request->parse_url = NULL; - request->url_prefix = "ssh"; - request->protocol_name = "SSH"; - request->need_hostport = 1; - request->need_userpass = ssh_need_userpass; - request->use_cache = 1; - request->use_threads = 1; - request->always_connected = 0; - request->protocol_data = g_malloc0 (sizeof (ssh_parms)); - gftp_set_config_options (request); + message->channel = buf[0]; + message->command = buf[1]; + memcpy (&message->len, buf + 2, 4); + message->len = ntohl (message->len); + if (message->len > 8192) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Error: Message size %d too big from server\n"), + message->len); + memset (message, 0, sizeof (*message)); + gftp_disconnect (request); + return (-1); + } + + message->data = g_malloc (message->len + 1); + + if (message->len > 0 && ssh_read_message (request, + (char *) message->data, message->len, fd) == NULL) + return (-1); + + ((char *) message->data)[message->len] = '\0'; + ssh_log_command (request, message->channel, message->command, message->data, + message->len, 0); + return (message->command); +} + + +static char * +ssh_read_line (gftp_request * request) +{ + char *retstr, *pos, tempchar; + ssh_parms *buffer; + + pos = NULL; + buffer = request->protocol_data; + if (!buffer->enddata && (pos = strchr (buffer->pos, '\n')) == NULL) + return (NULL); + + if (pos == NULL) + { + pos = buffer->pos + strlen (buffer->pos) - 1; + tempchar = '\0'; + } + else + tempchar = pos + 1 == '\0' ? '\0' : '1'; + + if (*(pos-1) == '\r') + *(pos-1) = '\0'; + else + *pos = '\0'; + + retstr = g_malloc (strlen (buffer->pos) + 1); + strcpy (retstr, buffer->pos); + + if (tempchar != '\0' && *buffer->pos != '\0') + { + buffer->pos = pos + 1; + while (*buffer->pos == '\r' || *buffer->pos == '\n') + buffer->pos++; + } + else + { + g_free (buffer->buffer); + buffer->buffer = buffer->pos = NULL; + } + return (retstr); } @@ -183,6 +299,55 @@ static int +ssh_chdir (gftp_request * request, const char *directory) +{ + ssh_message message; + int ret; + + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_SSH_NUM, -2); + + if (directory != NULL && *directory != '\0') + { + if (ssh_send_command (request, CHDIR, directory, + strlen (directory) + 1) < 0) + return (-1); + + if ((ret = ssh_read_response (request, &message, NULL)) != SUCCESS) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Could not change remote directory to %s: %s\n"), + directory, (char *) message.data); + g_free (message.data); + return (-1); + } + g_free (message.data); + } + + if (directory != request->directory) + { + if (ssh_send_command (request, GETDIR, NULL, 0) < 0) + return (-1); + + if (ssh_read_response (request, &message, NULL) != TELLDIR) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Could not get current working directory: %s\n"), + (char *) message.data); + g_free (message.data); + return (-1); + } + + if (request->directory) + g_free (request->directory); + request->directory = message.data; + } + + return (0); +} + + +static int ssh_connect (gftp_request * request) { char **args, *tempstr, pts_name[20], *p1, p2, *exepath, port[6]; @@ -566,6 +731,21 @@ } +static size_t +ssh_remove_spaces ( char *string ) +{ + size_t len; + char *pos; + + for (pos = string, len = 0; *pos != '\0'; len++, pos++) + { + if (*pos == ' ') + *pos = '\0'; + } + return (len); +} + + static int ssh_list_files (gftp_request * request) { @@ -733,55 +913,6 @@ } -static int -ssh_chdir (gftp_request * request, const char *directory) -{ - ssh_message message; - int ret; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_SSH_NUM, -2); - - if (directory != NULL && *directory != '\0') - { - if (ssh_send_command (request, CHDIR, directory, - strlen (directory) + 1) < 0) - return (-1); - - if ((ret = ssh_read_response (request, &message, NULL)) != SUCCESS) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Could not change remote directory to %s: %s\n"), - directory, (char *) message.data); - g_free (message.data); - return (-1); - } - g_free (message.data); - } - - if (directory != request->directory) - { - if (ssh_send_command (request, GETDIR, NULL, 0) < 0) - return (-1); - - if (ssh_read_response (request, &message, NULL) != TELLDIR) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Could not get current working directory: %s\n"), - (char *) message.data); - g_free (message.data); - return (-1); - } - - if (request->directory) - g_free (request->directory); - request->directory = message.data; - } - - return (0); -} - - static char * ssh_exec (gftp_request * request, const char *command, size_t len) { @@ -1007,230 +1138,45 @@ } -static int -ssh_send_command (gftp_request * request, int cmdnum, const char *command, - size_t len) +void +ssh_init (gftp_request * request) { - ssh_parms * params; - char *buf; - int clen; - - params = request->protocol_data; - clen = htonl (len); - buf = g_malloc (len + 6); - buf[0] = params->channel; - buf[1] = cmdnum; - memcpy (&buf[2], &clen, 4); - if (command) - memcpy (&buf[6], command, len); - ssh_log_command (request, params->channel, cmdnum, command, len, 1); - - if (gftp_fwrite (request, buf, len + 6, request->sockfd_write) < 0) - return (-2); - - return 0; - -} - -static int -ssh_read_response (gftp_request * request, ssh_message *message, FILE * fd) -{ - char buf[6]; - - if (ssh_read_message (request, buf, 6, fd) == NULL) - return (-1); + g_return_if_fail (request != NULL); - message->channel = buf[0]; - message->command = buf[1]; - memcpy (&message->len, buf + 2, 4); - message->len = ntohl (message->len); - if (message->len > 8192) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Error: Message size %d too big from server\n"), - message->len); - memset (message, 0, sizeof (*message)); - gftp_disconnect (request); - return (-1); - } - - message->data = g_malloc (message->len + 1); - - if (message->len > 0 && ssh_read_message (request, - (char *) message->data, message->len, fd) == NULL) - return (-1); - - ((char *) message->data)[message->len] = '\0'; - ssh_log_command (request, message->channel, message->command, message->data, - message->len, 0); - return (message->command); -} - - -static char * -ssh_read_message (gftp_request * request, char *buf, size_t len, FILE * fd) -{ - if (fd == NULL) - fd = request->sockfd; - - fread (buf, len, 1, fd); - if (ferror (fd)) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Error: Could not read from socket: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - return (NULL); - } - - return (buf); + request->protonum = GFTP_SSH_NUM; + request->init = ssh_init; + request->destroy = ssh_destroy; + request->connect = ssh_connect; + request->disconnect = ssh_disconnect; + request->get_file = ssh_get_file; + request->put_file = ssh_put_file; + request->transfer_file = NULL; + request->get_next_file_chunk = ssh_get_next_file_chunk; + request->put_next_file_chunk = ssh_put_next_file_chunk; + request->end_transfer = ssh_end_transfer; + request->abort_transfer = NULL; /* FIXME */ + request->list_files = ssh_list_files; + request->get_next_file = ssh_get_next_file; + request->set_data_type = NULL; + request->get_file_size = NULL; + request->chdir = ssh_chdir; + request->rmdir = ssh_rmdir; + request->rmfile = ssh_rmfile; + request->mkdir = ssh_mkdir; + request->rename = ssh_rename; + request->chmod = ssh_chmod; + request->set_file_time = NULL; + request->site = NULL; + request->parse_url = NULL; + request->url_prefix = "ssh"; + request->protocol_name = "SSH"; + request->need_hostport = 1; + request->need_userpass = ssh_need_userpass; + request->use_cache = 1; + request->use_threads = 1; + request->always_connected = 0; + request->protocol_data = g_malloc0 (sizeof (ssh_parms)); + gftp_set_config_options (request); } -static char * -ssh_read_line (gftp_request * request) -{ - char *retstr, *pos, tempchar; - ssh_parms *buffer; - - pos = NULL; - buffer = request->protocol_data; - if (!buffer->enddata && (pos = strchr (buffer->pos, '\n')) == NULL) - return (NULL); - - if (pos == NULL) - { - pos = buffer->pos + strlen (buffer->pos) - 1; - tempchar = '\0'; - } - else - tempchar = pos + 1 == '\0' ? '\0' : '1'; - - if (*(pos-1) == '\r') - *(pos-1) = '\0'; - else - *pos = '\0'; - - retstr = g_malloc (strlen (buffer->pos) + 1); - strcpy (retstr, buffer->pos); - - if (tempchar != '\0' && *buffer->pos != '\0') - { - buffer->pos = pos + 1; - while (*buffer->pos == '\r' || *buffer->pos == '\n') - buffer->pos++; - } - else - { - g_free (buffer->buffer); - buffer->buffer = buffer->pos = NULL; - } - return (retstr); -} - - -static void -ssh_log_command (gftp_request * request, int channel, int cmdnum, - const char *command, size_t len, int direction) -{ - const char *pos; - char *tempstr; - int ok; - - switch (cmdnum) - { - case CHDIR: - tempstr = "CHDIR "; - break; - case GETDIR: - tempstr = "GETDIR "; - break; - case TELLDIR: - tempstr = "TELLDIR "; - break; - case SENDFILE: - tempstr = "SENDFILE "; - break; - case FILESIZE: - tempstr = "FILESIZE "; - break; - case FILEMODE: - tempstr = "FILEMODE "; - break; - case ENDDATA: - tempstr = "ENDDATA "; - break; - case FILEOK: - tempstr = "FILEOK "; - break; - case STREAM: - tempstr = "STREAM "; - break; - case REQUEST: - tempstr = "REQUEST "; - break; - case FILENAME: - tempstr = "FILENAME "; - break; - case EXEC: - tempstr = "EXEC "; - break; - case SKIPBYTES: - tempstr = "SKIPBYTES "; - break; - case ERROR: - tempstr = "ERROR: "; - break; - case SUCCESS: - tempstr = "SUCCESS "; - break; - case CLOSE: - tempstr = "CLOSE "; - break; - case SSH_VERSION: - tempstr = "VERSION "; - break; - case CANCEL: - tempstr = "CANCEL "; - break; - case FILETIME: - tempstr = "FILETIME "; - break; - default: - return; - } - - ok = 0; - if (command) - { - for (pos = command; pos < command + len; pos++) - { - if (*pos == '\0') - { - ok = 1; - break; - } - } - } - - request->logging_function (direction == GFTP_DIRECTION_DOWNLOAD ? - gftp_logging_send : gftp_logging_recv, - request->user_data, "%d: %s %s\n", channel, - tempstr, ok ? command : ""); -} - - -static size_t -ssh_remove_spaces ( char *string ) -{ - size_t len; - char *pos; - - for (pos = string, len = 0; *pos != '\0'; len++, pos++) - { - if (*pos == ' ') - *pos = '\0'; - } - return (len); -} - diff -r eec25f215772 -r e5f6054590b5 lib/sshv2.c --- a/lib/sshv2.c Tue Nov 05 20:36:11 2002 +0000 +++ b/lib/sshv2.c Wed Nov 06 02:20:25 2002 +0000 @@ -61,68 +61,6 @@ } sshv2_params; -static void sshv2_destroy ( gftp_request * request ); -static int sshv2_connect ( gftp_request * request ); -static void sshv2_disconnect ( gftp_request * request ); -static gint32 sshv2_buffer_get_int32 ( gftp_request * request, - sshv2_message * buffer, - int expected_response ); -static char * sshv2_buffer_get_string ( gftp_request * request, - sshv2_message * buffer ); -static int sshv2_send_command ( gftp_request * request, - char type, - char *command, - gint32 len ); -static int sshv2_read_response ( gftp_request * request, - sshv2_message * message, - FILE * fd ); -static void sshv2_message_free ( sshv2_message * message ); -static void sshv2_log_command ( gftp_request * request, - gftp_logging_level level, - char type, - char *message, - size_t length ); -static int sshv2_end_transfer ( gftp_request * request ); -static int sshv2_list_files ( gftp_request * request ); -static int sshv2_get_next_file ( gftp_request * request, - gftp_file * fle, - FILE * fd ); -static int sshv2_chdir ( gftp_request * request, - const char *directory ); -static int sshv2_getcwd ( gftp_request * request ); -static int sshv2_rmdir ( gftp_request * request, - const char *directory ); -static int sshv2_rmfile ( gftp_request * request, - const char *file); -static int sshv2_chmod ( gftp_request * request, - const char *file, - int mode ); -static int sshv2_mkdir ( gftp_request * request, - const char *newdir ); -static int sshv2_rename ( gftp_request * request, - const char *oldname, - const char *newname ); -static int sshv2_set_file_time ( gftp_request * request, - const char *file, - time_t datetime ); -static off_t sshv2_get_file_size ( gftp_request * request, - const char *file ); -static long sshv2_get_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize ); -static int sshv2_put_file ( gftp_request * request, - const char *filename, - FILE * fd, - off_t startsize, - off_t totalsize ); -static size_t sshv2_get_next_file_chunk ( gftp_request * request, - char *buf, - size_t size ); -static size_t sshv2_put_next_file_chunk ( gftp_request * request, - char *buf, - size_t size ); - #define SSH_MY_VERSION 3 #define SSH_FXP_INIT 1 @@ -175,50 +113,271 @@ #define SSH_FX_OP_UNSUPPORTED 8 -void -sshv2_init (gftp_request * request) +static void +sshv2_log_command (gftp_request * request, gftp_logging_level level, + char type, char *message, size_t length) { + gint32 id, num, attr, stattype; + char *descr, *pos, oldchar; sshv2_params * params; - g_return_if_fail (request != NULL); + params = request->protocol_data; + memcpy (&id, message, 4); + id = ntohl (id); + switch (type) + { + case SSH_FXP_INIT: + request->logging_function (level, request->user_data, + _("%d: Protocol Initialization\n"), id); + break; + case SSH_FXP_VERSION: + memcpy (&num, message, 4); + num = ntohl (num); + request->logging_function (level, request->user_data, + _("%d: Protocol version %d\n"), id, num); + break; + case SSH_FXP_OPEN: + memcpy (&num, message + 4, 4); + num = ntohl (num); + pos = message + 12 + num - 1; + oldchar = *pos; + *pos = '\0'; + request->logging_function (level, request->user_data, + _("%d: Open %s\n"), id, message + 8); + *pos = oldchar; + break; + case SSH_FXP_CLOSE: + request->logging_function (level, request->user_data, + _("%d: Close\n"), id); + case SSH_FXP_READ: + case SSH_FXP_WRITE: + break; + case SSH_FXP_OPENDIR: + request->logging_function (level, request->user_data, + _("%d: Open Directory %s\n"), id, + message + 8); + break; + case SSH_FXP_READDIR: + request->logging_function (level, request->user_data, + _("%d: Read Directory\n"), id); + break; + case SSH_FXP_REMOVE: + request->logging_function (level, request->user_data, + _("%d: Remove file %s\n"), id, + message + 8); + break; + case SSH_FXP_MKDIR: + request->logging_function (level, request->user_data, + _("%d: Make directory %s\n"), id, + message + 8); + break; + case SSH_FXP_RMDIR: + request->logging_function (level, request->user_data, + _("%d: Remove directory %s\n"), id, + message + 8); + break; + case SSH_FXP_REALPATH: + request->logging_function (level, request->user_data, + _("%d: Realpath %s\n"), id, + message + 8); + break; + case SSH_FXP_ATTRS: + request->logging_function (level, request->user_data, + _("%d: File attributes\n"), id); + break; + case SSH_FXP_STAT: + request->logging_function (level, request->user_data, + _("%d: Stat %s\n"), id, + message + 8); + break; + case SSH_FXP_SETSTAT: + memcpy (&num, message + 4, 4); + num = ntohl (num); + pos = message + 12 + num - 1; + oldchar = *pos; + *pos = '\0'; + memcpy (&stattype, message + 8 + num, 4); + stattype = ntohl (stattype); + memcpy (&attr, message + 12 + num, 4); + attr = ntohl (attr); + switch (stattype) + { + case SSH_FILEXFER_ATTR_PERMISSIONS: + request->logging_function (level, request->user_data, + _("%d: Chmod %s %o\n"), id, + message + 8, attr); + break; + case SSH_FILEXFER_ATTR_ACMODTIME: + request->logging_function (level, request->user_data, + _("%d: Utime %s %d\n"), id, + message + 8, attr); + } + *pos = oldchar; + break; + case SSH_FXP_STATUS: + if (params->dont_log_status) + break; + memcpy (&num, message + 4, 4); + num = ntohl (num); + switch (num) + { + case SSH_FX_OK: + descr = _("OK"); + break; + case SSH_FX_EOF: + descr = _("EOF"); + break; + case SSH_FX_NO_SUCH_FILE: + descr = _("No such file or directory"); + break; + case SSH_FX_PERMISSION_DENIED: + descr = _("Permission denied"); + break; + case SSH_FX_FAILURE: + descr = _("Failure"); + break; + case SSH_FX_BAD_MESSAGE: + descr = _("Bad message"); + break; + case SSH_FX_NO_CONNECTION: + descr = _("No connection"); + break; + case SSH_FX_CONNECTION_LOST: + descr = _("Connection lost"); + break; + case SSH_FX_OP_UNSUPPORTED: + descr = _("Operation unsupported"); + break; + default: + descr = _("Unknown message returned from server"); + break; + } + request->logging_function (level, request->user_data, + "%d: %s\n", id, descr); + break; + case SSH_FXP_HANDLE: + request->logging_function (level, request->user_data, + "%d: File handle\n", id); + break; + case SSH_FXP_DATA: + break; + case SSH_FXP_NAME: + memcpy (&num, message + 4, 4); + num = ntohl (num); + request->logging_function (level, request->user_data, + "%d: Filenames (%d entries)\n", id, + num); + break; + default: + request->logging_function (level, request->user_data, + "Command: %x\n", type); + } +} - request->protonum = GFTP_SSHV2_NUM; - request->init = sshv2_init; - request->destroy = sshv2_destroy; - request->connect = sshv2_connect; - request->disconnect = sshv2_disconnect; - request->get_file = sshv2_get_file; - request->put_file = sshv2_put_file; - request->transfer_file = NULL; - request->get_next_file_chunk = sshv2_get_next_file_chunk; - request->put_next_file_chunk = sshv2_put_next_file_chunk; - request->end_transfer = sshv2_end_transfer; - request->abort_transfer = NULL; /* FIXME */ - request->list_files = sshv2_list_files; - request->get_next_file = sshv2_get_next_file; - request->set_data_type = NULL; - request->get_file_size = sshv2_get_file_size; - request->chdir = sshv2_chdir; - request->rmdir = sshv2_rmdir; - request->rmfile = sshv2_rmfile; - request->mkdir = sshv2_mkdir; - request->rename = sshv2_rename; - request->chmod = sshv2_chmod; - request->set_file_time = sshv2_set_file_time; - request->site = NULL; - request->parse_url = NULL; - request->url_prefix = "ssh2"; - request->protocol_name = "SSH2"; - request->need_hostport = 1; - request->need_userpass = ssh_need_userpass; - request->use_cache = 1; - request->use_threads = 1; - request->always_connected = 0; - request->protocol_data = g_malloc0 (sizeof (sshv2_params)); - gftp_set_config_options (request); + +static int +sshv2_send_command (gftp_request * request, char type, char *command, + gint32 len) +{ + char buf[34000]; + gint32 clen; + + if (len > 33995) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Error: Message size %d too big\n"), len); + gftp_disconnect (request); + return (-1); + } + + clen = htonl (len + 1); + memcpy (buf, &clen, 4); + buf[4] = type; + memcpy (&buf[5], command, len); + buf[len + 5] = '\0'; + +#ifdef DEBUG + printf ("\rSending: "); + for (wrote=0; wrotesockfd_write) < 0) + return (-2); + + return 0; +} + + +static int +sshv2_read_response (gftp_request * request, sshv2_message * message, + FILE * fd) +{ + ssize_t numread; + char buf[5]; + + if (fd == NULL) + fd = request->sockfd; - params = request->protocol_data; - params->id = 1; + numread = fread (buf, 5, 1, fd); + if (ferror (fd)) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Error: Could not read from socket: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + return (-1); + } + +#ifdef DEBUG + printf ("\rReceived: "); + for (numread=0; numread<5; numread++) + printf ("%x ", buf[numread]); + fflush (stdout); +#endif + + memcpy (&message->length, buf, 4); + message->length = ntohl (message->length); + if (message->length > 34000) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Error: Message size %d too big from server\n"), + message->length); + memset (message, 0, sizeof (*message)); + gftp_disconnect (request); + return (-1); + } + message->command = buf[4]; + message->buffer = g_malloc (message->length); + + message->pos = message->buffer; + message->end = message->buffer + message->length - 1; + + numread = fread (message->buffer, message->length - 1, 1, fd); + if (ferror (fd)) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Error: Could not read from socket: %s\n"), + g_strerror (errno)); + gftp_disconnect (request); + return (-1); + } + message->buffer[message->length - 1] = '\0'; + +#ifdef DEBUG + printf ("\rReceived: "); + for (numread=0; numreadlength - 1; numread++) + printf ("%x ", message->buffer[numread]); + printf ("\n"); +#endif + + sshv2_log_command (request, gftp_logging_recv, message->command, + message->buffer, message->length); + + return (message->command); } @@ -233,6 +392,134 @@ } +static void +sshv2_message_free (sshv2_message * message) +{ + if (message->buffer) + g_free (message->buffer); + memset (message, 0, sizeof (*message)); +} + + +static gint32 +sshv2_buffer_get_int32 (gftp_request * request, sshv2_message * message, + int expected_response) +{ + gint32 ret; + + if (message->end - message->pos < 4) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Received wrong response from server, disconnecting\n")); + sshv2_message_free (message); + gftp_disconnect (request); + return (-2); + } + + memcpy (&ret, message->pos, 4); + ret = ntohl (ret); + message->pos += 4; + + if (expected_response > 0 && ret != expected_response) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Received wrong response from server, disconnecting\n")); + sshv2_message_free (message); + gftp_disconnect (request); + return (-2); + } + + return (ret); +} + + +static char * +sshv2_buffer_get_string (gftp_request * request, sshv2_message * message) +{ + char *string; + gint32 len; + + if ((len = sshv2_buffer_get_int32 (request, message, -1)) < 0) + return (NULL); + + if (len > SSH_MAX_STRING_SIZE || (message->end - message->pos < len)) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Received wrong response from server, disconnecting\n")); + sshv2_message_free (message); + gftp_disconnect (request); + return (NULL); + } + + string = g_malloc (len + 1); + memcpy (string, message->pos, len); + string[len] = '\0'; + message->pos += len; + return (string); +} + + +static int +sshv2_getcwd (gftp_request * request) +{ + sshv2_message message; + sshv2_params * params; + char *tempstr, *dir; + gint32 num; + size_t len; + + g_return_val_if_fail (request != NULL, -2); + g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2); + + if (request->directory == NULL || *request->directory == '\0') + dir = "."; + else + dir = request->directory; + + params = request->protocol_data; + len = strlen (dir); + tempstr = g_malloc (len + 9); + strcpy (tempstr + 8, dir); + + num = htonl (params->id++); + memcpy (tempstr, &num, 4); + + num = htonl (len); + memcpy (tempstr + 4, &num, 4); + if (sshv2_send_command (request, SSH_FXP_REALPATH, tempstr, len + 8) < 0) + { + g_free (tempstr); + return (-2); + } + + g_free (tempstr); + if (request->directory) + { + g_free (request->directory); + request->directory = NULL; + } + + memset (&message, 0, sizeof (message)); + if (sshv2_read_response (request, &message, NULL) != SSH_FXP_NAME) + { + request->logging_function (gftp_logging_error, request->user_data, + _("Received wrong response from server, disconnecting\n")); + sshv2_message_free (&message); + gftp_disconnect (request); + return (-2); + } + + message.pos += 4; + if (sshv2_buffer_get_int32 (request, &message, 1) < 0) + return (-2); + + if ((request->directory = sshv2_buffer_get_string (request, &message)) == NULL) + return (-2); + sshv2_message_free (&message); + return (0); +} + + static int sshv2_connect (gftp_request * request) { @@ -436,341 +723,6 @@ } -static gint32 -sshv2_buffer_get_int32 (gftp_request * request, sshv2_message * message, - int expected_response) -{ - gint32 ret; - - if (message->end - message->pos < 4) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Received wrong response from server, disconnecting\n")); - sshv2_message_free (message); - gftp_disconnect (request); - return (-2); - } - - memcpy (&ret, message->pos, 4); - ret = ntohl (ret); - message->pos += 4; - - if (expected_response > 0 && ret != expected_response) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Received wrong response from server, disconnecting\n")); - sshv2_message_free (message); - gftp_disconnect (request); - return (-2); - } - - return (ret); -} - - -static char * -sshv2_buffer_get_string (gftp_request * request, sshv2_message * message) -{ - char *string; - gint32 len; - - if ((len = sshv2_buffer_get_int32 (request, message, -1)) < 0) - return (NULL); - - if (len > SSH_MAX_STRING_SIZE || (message->end - message->pos < len)) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Received wrong response from server, disconnecting\n")); - sshv2_message_free (message); - gftp_disconnect (request); - return (NULL); - } - - string = g_malloc (len + 1); - memcpy (string, message->pos, len); - string[len] = '\0'; - message->pos += len; - return (string); -} - - -static int -sshv2_send_command (gftp_request * request, char type, char *command, - gint32 len) -{ - char buf[34000]; - gint32 clen; - - if (len > 33995) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Error: Message size %d too big\n"), len); - gftp_disconnect (request); - return (-1); - } - - clen = htonl (len + 1); - memcpy (buf, &clen, 4); - buf[4] = type; - memcpy (&buf[5], command, len); - buf[len + 5] = '\0'; - -#ifdef DEBUG - printf ("\rSending: "); - for (wrote=0; wrotesockfd_write) < 0) - return (-2); - - return 0; -} - - -static int -sshv2_read_response (gftp_request * request, sshv2_message * message, - FILE * fd) -{ - ssize_t numread; - char buf[5]; - - if (fd == NULL) - fd = request->sockfd; - - numread = fread (buf, 5, 1, fd); - if (ferror (fd)) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Error: Could not read from socket: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - return (-1); - } - -#ifdef DEBUG - printf ("\rReceived: "); - for (numread=0; numread<5; numread++) - printf ("%x ", buf[numread]); - fflush (stdout); -#endif - - memcpy (&message->length, buf, 4); - message->length = ntohl (message->length); - if (message->length > 34000) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Error: Message size %d too big from server\n"), - message->length); - memset (message, 0, sizeof (*message)); - gftp_disconnect (request); - return (-1); - } - message->command = buf[4]; - message->buffer = g_malloc (message->length); - - message->pos = message->buffer; - message->end = message->buffer + message->length - 1; - - numread = fread (message->buffer, message->length - 1, 1, fd); - if (ferror (fd)) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Error: Could not read from socket: %s\n"), - g_strerror (errno)); - gftp_disconnect (request); - return (-1); - } - message->buffer[message->length - 1] = '\0'; - -#ifdef DEBUG - printf ("\rReceived: "); - for (numread=0; numreadlength - 1; numread++) - printf ("%x ", message->buffer[numread]); - printf ("\n"); -#endif - - sshv2_log_command (request, gftp_logging_recv, message->command, - message->buffer, message->length); - - return (message->command); -} - - -static void -sshv2_message_free (sshv2_message * message) -{ - if (message->buffer) - g_free (message->buffer); - memset (message, 0, sizeof (*message)); -} - - -static void -sshv2_log_command (gftp_request * request, gftp_logging_level level, - char type, char *message, size_t length) -{ - gint32 id, num, attr, stattype; - char *descr, *pos, oldchar; - sshv2_params * params; - - params = request->protocol_data; - memcpy (&id, message, 4); - id = ntohl (id); - switch (type) - { - case SSH_FXP_INIT: - request->logging_function (level, request->user_data, - _("%d: Protocol Initialization\n"), id); - break; - case SSH_FXP_VERSION: - memcpy (&num, message, 4); - num = ntohl (num); - request->logging_function (level, request->user_data, - _("%d: Protocol version %d\n"), id, num); - break; - case SSH_FXP_OPEN: - memcpy (&num, message + 4, 4); - num = ntohl (num); - pos = message + 12 + num - 1; - oldchar = *pos; - *pos = '\0'; - request->logging_function (level, request->user_data, - _("%d: Open %s\n"), id, message + 8); - *pos = oldchar; - break; - case SSH_FXP_CLOSE: - request->logging_function (level, request->user_data, - _("%d: Close\n"), id); - case SSH_FXP_READ: - case SSH_FXP_WRITE: - break; - case SSH_FXP_OPENDIR: - request->logging_function (level, request->user_data, - _("%d: Open Directory %s\n"), id, - message + 8); - break; - case SSH_FXP_READDIR: - request->logging_function (level, request->user_data, - _("%d: Read Directory\n"), id); - break; - case SSH_FXP_REMOVE: - request->logging_function (level, request->user_data, - _("%d: Remove file %s\n"), id, - message + 8); - break; - case SSH_FXP_MKDIR: - request->logging_function (level, request->user_data, - _("%d: Make directory %s\n"), id, - message + 8); - break; - case SSH_FXP_RMDIR: - request->logging_function (level, request->user_data, - _("%d: Remove directory %s\n"), id, - message + 8); - break; - case SSH_FXP_REALPATH: - request->logging_function (level, request->user_data, - _("%d: Realpath %s\n"), id, - message + 8); - break; - case SSH_FXP_ATTRS: - request->logging_function (level, request->user_data, - _("%d: File attributes\n"), id); - break; - case SSH_FXP_STAT: - request->logging_function (level, request->user_data, - _("%d: Stat %s\n"), id, - message + 8); - break; - case SSH_FXP_SETSTAT: - memcpy (&num, message + 4, 4); - num = ntohl (num); - pos = message + 12 + num - 1; - oldchar = *pos; - *pos = '\0'; - memcpy (&stattype, message + 8 + num, 4); - stattype = ntohl (stattype); - memcpy (&attr, message + 12 + num, 4); - attr = ntohl (attr); - switch (stattype) - { - case SSH_FILEXFER_ATTR_PERMISSIONS: - request->logging_function (level, request->user_data, - _("%d: Chmod %s %o\n"), id, - message + 8, attr); - break; - case SSH_FILEXFER_ATTR_ACMODTIME: - request->logging_function (level, request->user_data, - _("%d: Utime %s %d\n"), id, - message + 8, attr); - } - *pos = oldchar; - break; - case SSH_FXP_STATUS: - if (params->dont_log_status) - break; - memcpy (&num, message + 4, 4); - num = ntohl (num); - switch (num) - { - case SSH_FX_OK: - descr = _("OK"); - break; - case SSH_FX_EOF: - descr = _("EOF"); - break; - case SSH_FX_NO_SUCH_FILE: - descr = _("No such file or directory"); - break; - case SSH_FX_PERMISSION_DENIED: - descr = _("Permission denied"); - break; - case SSH_FX_FAILURE: - descr = _("Failure"); - break; - case SSH_FX_BAD_MESSAGE: - descr = _("Bad message"); - break; - case SSH_FX_NO_CONNECTION: - descr = _("No connection"); - break; - case SSH_FX_CONNECTION_LOST: - descr = _("Connection lost"); - break; - case SSH_FX_OP_UNSUPPORTED: - descr = _("Operation unsupported"); - break; - default: - descr = _("Unknown message returned from server"); - break; - } - request->logging_function (level, request->user_data, - "%d: %s\n", id, descr); - break; - case SSH_FXP_HANDLE: - request->logging_function (level, request->user_data, - "%d: File handle\n", id); - break; - case SSH_FXP_DATA: - break; - case SSH_FXP_NAME: - memcpy (&num, message + 4, 4); - num = ntohl (num); - request->logging_function (level, request->user_data, - "%d: Filenames (%d entries)\n", id, - num); - break; - default: - request->logging_function (level, request->user_data, - "Command: %x\n", type); - } -} - - static int sshv2_end_transfer (gftp_request * request) { @@ -1144,67 +1096,6 @@ } -static int -sshv2_getcwd (gftp_request * request) -{ - sshv2_message message; - sshv2_params * params; - char *tempstr, *dir; - gint32 num; - size_t len; - - g_return_val_if_fail (request != NULL, -2); - g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, -2); - - if (request->directory == NULL || *request->directory == '\0') - dir = "."; - else - dir = request->directory; - - params = request->protocol_data; - len = strlen (dir); - tempstr = g_malloc (len + 9); - strcpy (tempstr + 8, dir); - - num = htonl (params->id++); - memcpy (tempstr, &num, 4); - - num = htonl (len); - memcpy (tempstr + 4, &num, 4); - if (sshv2_send_command (request, SSH_FXP_REALPATH, tempstr, len + 8) < 0) - { - g_free (tempstr); - return (-2); - } - - g_free (tempstr); - if (request->directory) - { - g_free (request->directory); - request->directory = NULL; - } - - memset (&message, 0, sizeof (message)); - if (sshv2_read_response (request, &message, NULL) != SSH_FXP_NAME) - { - request->logging_function (gftp_logging_error, request->user_data, - _("Received wrong response from server, disconnecting\n")); - sshv2_message_free (&message); - gftp_disconnect (request); - return (-2); - } - - message.pos += 4; - if (sshv2_buffer_get_int32 (request, &message, 1) < 0) - return (-2); - - if ((request->directory = sshv2_buffer_get_string (request, &message)) == NULL) - return (-2); - sshv2_message_free (&message); - return (0); -} - - static int sshv2_rmdir (gftp_request * request, const char *directory) { @@ -1986,3 +1877,50 @@ return (size); } + +void +sshv2_init (gftp_request * request) +{ + sshv2_params * params; + + g_return_if_fail (request != NULL); + + request->protonum = GFTP_SSHV2_NUM; + request->init = sshv2_init; + request->destroy = sshv2_destroy; + request->connect = sshv2_connect; + request->disconnect = sshv2_disconnect; + request->get_file = sshv2_get_file; + request->put_file = sshv2_put_file; + request->transfer_file = NULL; + request->get_next_file_chunk = sshv2_get_next_file_chunk; + request->put_next_file_chunk = sshv2_put_next_file_chunk; + request->end_transfer = sshv2_end_transfer; + request->abort_transfer = sshv2_end_transfer; /* NOTE: uses sshv2_end_transfer */ + request->list_files = sshv2_list_files; + request->get_next_file = sshv2_get_next_file; + request->set_data_type = NULL; + request->get_file_size = sshv2_get_file_size; + request->chdir = sshv2_chdir; + request->rmdir = sshv2_rmdir; + request->rmfile = sshv2_rmfile; + request->mkdir = sshv2_mkdir; + request->rename = sshv2_rename; + request->chmod = sshv2_chmod; + request->set_file_time = sshv2_set_file_time; + request->site = NULL; + request->parse_url = NULL; + request->url_prefix = "ssh2"; + request->protocol_name = "SSH2"; + request->need_hostport = 1; + request->need_userpass = ssh_need_userpass; + request->use_cache = 1; + request->use_threads = 1; + request->always_connected = 0; + request->protocol_data = g_malloc0 (sizeof (sshv2_params)); + gftp_set_config_options (request); + + params = request->protocol_data; + params->id = 1; +} + diff -r eec25f215772 -r e5f6054590b5 src/gtk/bookmarks.c --- a/src/gtk/bookmarks.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/bookmarks.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,39 +20,6 @@ #include "gftp-gtk.h" static const char cvsid[] = "$Id$"; -static void doadd_bookmark ( gpointer * data, - gftp_dialog_data * ddata); -static void bm_apply_changes ( GtkWidget * widget, - gpointer backup_data ); -static gftp_bookmarks * copy_bookmarks ( gftp_bookmarks * bookmarks ); -static void bm_close_dialog ( GtkWidget * widget, - GtkWidget * dialog ); -static void after_move ( GtkCTree * ctree, - GtkCTreeNode * child, - GtkCTreeNode * parent, - GtkCTreeNode * sibling, - gpointer data ); -static gint bm_dblclick ( GtkWidget * widget, - GdkEventButton * event, - gpointer data ); -static gint bm_enter ( GtkWidget * widget, - GdkEventKey * event, - gpointer data ); -static void new_folder_entry ( gpointer data ); -static void do_make_new ( gpointer data, - gftp_dialog_data * ddata ); -static void new_item_entry ( gpointer data ); -static void edit_entry ( gpointer data ); -static void delete_entry ( gpointer data ); -static void do_delete_entry ( gftp_bookmarks * entry, - gftp_dialog_data * ddata ); -static void entry_apply_changes ( GtkWidget * widget, - gftp_bookmarks * entry ); -static void set_userpass_visible ( GtkWidget * checkbutton, - GtkWidget * entry ); -static void build_bookmarks_tree ( void ); -static void clear_bookmarks_tree ( void ); - static GtkWidget * bm_hostedit, * bm_portedit, * bm_localdiredit, * bm_remotediredit, * bm_useredit, * bm_passedit, * bm_acctedit, * anon_chk, * bm_pathedit, * bm_protocol, * tree, *bm_sftppath; @@ -132,25 +99,6 @@ ftp_connect (current_wdata, current_wdata->request, 1); } -void -add_bookmark (gpointer data) -{ - const char *edttxt; - - if (!check_status (_("Add Bookmark"), current_wdata, 0, 0, 0, 1)) - return; - - edttxt = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (hostedit)->entry)); - if (*edttxt == '\0') - { - ftp_log (gftp_logging_error, NULL, - _("Add Bookmark: You must enter a hostname\n")); - return; - } - - MakeEditDialog (_("Add Bookmark"), _("Enter the name of the bookmark you want to add\nYou can separate items by a / to put it into a submenu\n(ex: Linux Sites/Debian)"), NULL, 1, _("Remember password"), gftp_dialog_button_create, doadd_bookmark, data, NULL, NULL); -} - static void doadd_bookmark (gpointer * data, gftp_dialog_data * ddata) @@ -230,6 +178,26 @@ void +add_bookmark (gpointer data) +{ + const char *edttxt; + + if (!check_status (_("Add Bookmark"), current_wdata, 0, 0, 0, 1)) + return; + + edttxt = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (hostedit)->entry)); + if (*edttxt == '\0') + { + ftp_log (gftp_logging_error, NULL, + _("Add Bookmark: You must enter a hostname\n")); + return; + } + + MakeEditDialog (_("Add Bookmark"), _("Enter the name of the bookmark you want to add\nYou can separate items by a / to put it into a submenu\n(ex: Linux Sites/Debian)"), NULL, 1, _("Remember password"), gftp_dialog_button_create, doadd_bookmark, data, NULL, NULL); +} + + +void build_bookmarks_menu (void) { GtkItemFactoryEntry test = { NULL, NULL, NULL, 0 }; @@ -265,132 +233,6 @@ } -#if GTK_MAJOR_VERSION > 1 -static void -editbm_action (GtkWidget * widget, gint response, gpointer user_data) -{ - switch (response) - { - case GTK_RESPONSE_OK: - bm_apply_changes (widget, NULL); - /* no break */ - default: - bm_close_dialog (NULL, widget); - } -} -#endif - - -void -edit_bookmarks (gpointer data) -{ - GtkWidget * dialog, * scroll; - GtkItemFactory * ifactory; - GtkItemFactoryEntry menu_items[] = { - {N_("/_File"), NULL, 0, 0, ""}, - {N_("/File/tearoff"), NULL, 0, 0, ""}, - {N_("/File/New Folder..."), NULL, new_folder_entry, 0, MN_(NULL)}, - {N_("/File/New Item..."), NULL, new_item_entry, 0, MS_(GTK_STOCK_NEW)}, - {N_("/File/Delete"), NULL, delete_entry, 0, MS_(GTK_STOCK_DELETE)}, - {N_("/File/Properties..."), NULL, edit_entry, 0, MS_(GTK_STOCK_PROPERTIES)}, - {N_("/File/sep"), NULL, 0, 0, ""}, - {N_("/File/Close"), NULL, gtk_widget_destroy, 0, MS_(GTK_STOCK_CLOSE)} - }; -#if GTK_MAJOR_VERSION == 1 - GtkWidget * tempwid; -#endif - - new_bookmarks = copy_bookmarks (bookmarks); - new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks); - -#if GTK_MAJOR_VERSION == 1 - dialog = gtk_dialog_new (); - gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Bookmarks")); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15); -#else - dialog = gtk_dialog_new_with_buttons (_("Edit Bookmarks"), NULL, 0, - GTK_STOCK_SAVE, - GTK_RESPONSE_OK, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - NULL); -#endif - gtk_window_set_wmclass (GTK_WINDOW(dialog), "Edit Bookmarks", "gFTP"); - gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); - gtk_widget_realize (dialog); - - if (gftp_icon != NULL) - { - gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap, - gftp_icon->bitmap); - gdk_window_set_icon_name (dialog->window, _("gFTP Icon")); - } - - /* FIXME - memory leak */ - ifactory = item_factory_new (GTK_TYPE_MENU_BAR, "", NULL, NULL); - create_item_factory (ifactory, 7, menu_items, NULL); - create_item_factory (ifactory, 1, menu_items + 7, dialog); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), ifactory->widget, - FALSE, FALSE, 0); - gtk_widget_show (ifactory->widget); - - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_widget_set_size_request (scroll, 150, 200); - - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scroll, TRUE, TRUE, - 0); - gtk_container_border_width (GTK_CONTAINER (scroll), 3); - gtk_widget_show (scroll); - - /* FIXME - memory leak */ - edit_factory = item_factory_new (GTK_TYPE_MENU, "", NULL, "/File"); - - create_item_factory (edit_factory, 6, menu_items + 2, dialog); - - tree = gtk_ctree_new (1, 0); - gtk_clist_set_selection_mode (GTK_CLIST (tree), GTK_SELECTION_BROWSE); - gtk_clist_set_reorderable (GTK_CLIST (tree), 1); - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), tree); - gtk_signal_connect_after (GTK_OBJECT (tree), "key_press_event", - GTK_SIGNAL_FUNC (bm_enter), (gpointer) tree); - gtk_signal_connect_after (GTK_OBJECT (tree), "tree_move", - GTK_SIGNAL_FUNC (after_move), NULL); - gtk_signal_connect_after (GTK_OBJECT (tree), "button_press_event", - GTK_SIGNAL_FUNC (bm_dblclick), (gpointer) tree); - gtk_widget_show (tree); - -#if GTK_MAJOR_VERSION == 1 - tempwid = gtk_button_new_with_label (_("OK")); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, - TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (bm_apply_changes), NULL); - gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog); - GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); - gtk_widget_show (tempwid); - - tempwid = gtk_button_new_with_label (_(" Cancel ")); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, - TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog); - GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); - gtk_widget_grab_focus (tempwid); - gtk_widget_show (tempwid); -#else - g_signal_connect (GTK_OBJECT (dialog), "response", - G_CALLBACK (editbm_action), NULL); -#endif - - gtk_widget_show (dialog); - - build_bookmarks_tree (); -} - - static void free_bookmark_entry_items (gftp_bookmarks * entry) { @@ -411,87 +253,6 @@ } -static void -bm_apply_changes (GtkWidget * widget, gpointer backup_data) -{ - gftp_bookmarks * tempentry, * delentry; - char *tempstr; - - tempentry = bookmarks->children; - while (tempentry != NULL) - { - if (tempentry->path && !tempentry->isfolder) - { - tempstr = g_strdup_printf ("/Bookmarks/%s", tempentry->path); - gtk_widget_destroy (gtk_item_factory_get_item (factory, tempstr)); - g_free (tempentry->path); - g_free (tempstr); - } - - free_bookmark_entry_items (tempentry); - - if (tempentry->children != NULL) - tempentry = tempentry->children; - else - { - if (tempentry->next == NULL) - { - while (tempentry->next == NULL && tempentry->prev != NULL) - { - delentry = tempentry; - tempentry = tempentry->prev; - if (delentry->isfolder) - { - tempstr = g_strdup_printf ("/Bookmarks/%s", - delentry->path); - gtk_widget_destroy (gtk_item_factory_get_item (factory, - tempstr)); - g_free (tempstr); - g_free (delentry->path); - } - g_free (delentry); - } - delentry = tempentry; - tempentry = tempentry->next; - if (delentry->isfolder && tempentry != NULL) - { - tempstr = g_strdup_printf ("/Bookmarks/%s", - delentry->path); - gtk_widget_destroy (gtk_item_factory_get_item (factory, - tempstr)); - g_free (delentry->path); - g_free (tempstr); - g_free (delentry); - } - } - else - { - delentry = tempentry; - tempentry = tempentry->next; - g_free (delentry); - } - } - } - g_free (bookmarks); - g_hash_table_destroy (bookmarks_htable); - - bookmarks = new_bookmarks; - bookmarks_htable = new_bookmarks_htable; - if (backup_data) - { - new_bookmarks = copy_bookmarks (bookmarks); - new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks); - } - else - { - new_bookmarks = NULL; - new_bookmarks_htable = NULL; - } - build_bookmarks_menu (); - gftp_write_bookmarks_file (); -} - - static gftp_bookmarks * copy_bookmarks (gftp_bookmarks * bookmarks) { @@ -605,6 +366,87 @@ static void +bm_apply_changes (GtkWidget * widget, gpointer backup_data) +{ + gftp_bookmarks * tempentry, * delentry; + char *tempstr; + + tempentry = bookmarks->children; + while (tempentry != NULL) + { + if (tempentry->path && !tempentry->isfolder) + { + tempstr = g_strdup_printf ("/Bookmarks/%s", tempentry->path); + gtk_widget_destroy (gtk_item_factory_get_item (factory, tempstr)); + g_free (tempentry->path); + g_free (tempstr); + } + + free_bookmark_entry_items (tempentry); + + if (tempentry->children != NULL) + tempentry = tempentry->children; + else + { + if (tempentry->next == NULL) + { + while (tempentry->next == NULL && tempentry->prev != NULL) + { + delentry = tempentry; + tempentry = tempentry->prev; + if (delentry->isfolder) + { + tempstr = g_strdup_printf ("/Bookmarks/%s", + delentry->path); + gtk_widget_destroy (gtk_item_factory_get_item (factory, + tempstr)); + g_free (tempstr); + g_free (delentry->path); + } + g_free (delentry); + } + delentry = tempentry; + tempentry = tempentry->next; + if (delentry->isfolder && tempentry != NULL) + { + tempstr = g_strdup_printf ("/Bookmarks/%s", + delentry->path); + gtk_widget_destroy (gtk_item_factory_get_item (factory, + tempstr)); + g_free (delentry->path); + g_free (tempstr); + g_free (delentry); + } + } + else + { + delentry = tempentry; + tempentry = tempentry->next; + g_free (delentry); + } + } + } + g_free (bookmarks); + g_hash_table_destroy (bookmarks_htable); + + bookmarks = new_bookmarks; + bookmarks_htable = new_bookmarks_htable; + if (backup_data) + { + new_bookmarks = copy_bookmarks (bookmarks); + new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks); + } + else + { + new_bookmarks = NULL; + new_bookmarks_htable = NULL; + } + build_bookmarks_menu (); + gftp_write_bookmarks_file (); +} + + +static void bm_close_dialog (GtkWidget * widget, GtkWidget * dialog) { gftp_bookmarks * tempentry, * delentry; @@ -642,142 +484,20 @@ } +#if GTK_MAJOR_VERSION > 1 static void -after_move (GtkCTree * ctree, GtkCTreeNode * child, GtkCTreeNode * parent, - GtkCTreeNode * sibling, gpointer data) +editbm_action (GtkWidget * widget, gint response, gpointer user_data) { - - gftp_bookmarks * childentry, * siblingentry, * parententry, * tempentry; - char *tempstr, *pos, *stpos; - - childentry = gtk_ctree_node_get_row_data (ctree, child); - parententry = gtk_ctree_node_get_row_data (ctree, parent); - siblingentry = gtk_ctree_node_get_row_data (ctree, sibling); - - tempentry = childentry->prev->children; - if (tempentry == childentry) - childentry->prev->children = childentry->prev->children->next; - else - { - while (tempentry->next != childentry) - tempentry = tempentry->next; - tempentry->next = childentry->next; - } - childentry->prev = parententry; - if (!parententry->isfolder) - { - childentry->next = parententry->children; - parententry->children = childentry; - gtk_ctree_move (ctree, child, parententry->prev->cnode, - parententry->cnode); - } - else + switch (response) { - if (siblingentry == NULL || parententry->children == siblingentry) - { - childentry->next = parententry->children; - parententry->children = childentry; - } - else - { - tempentry = parententry->children; - while (tempentry->next != siblingentry) - tempentry = tempentry->next; - childentry->next = tempentry->next; - tempentry->next = childentry; - } - - tempentry = childentry; - while (tempentry != NULL) - { - g_hash_table_remove (new_bookmarks_htable, tempentry->path); - if ((pos = strrchr (tempentry->path, '/')) == NULL) - pos = tempentry->path; - else - pos++; - tempstr = g_strdup_printf ("%s/%s", tempentry->prev->path, pos); - for (stpos = tempstr; *stpos == '/'; stpos++); - g_free (tempentry->path); - tempentry->path = g_malloc (strlen (stpos) + 1); - strcpy (tempentry->path, stpos); - g_free (tempstr); - g_hash_table_insert (new_bookmarks_htable, tempentry->path, - tempentry); - if (tempentry->children != NULL) - tempentry = tempentry->children; - else - { - if (tempentry->next == NULL) - { - if (tempentry->prev == childentry) - break; - else - { - while (tempentry->next == NULL - && tempentry->prev != NULL) - tempentry = tempentry->prev; - } - } - tempentry = tempentry->next; - } - } + case GTK_RESPONSE_OK: + bm_apply_changes (widget, NULL); + /* no break */ + default: + bm_close_dialog (NULL, widget); } } - - -static gint -bm_dblclick (GtkWidget * widget, GdkEventButton * event, gpointer data) -{ - if (event->button == 3) - gtk_item_factory_popup (edit_factory, (guint) event->x_root, - (guint) event->y_root, 1, 0); - else if (event->type == GDK_2BUTTON_PRESS) - { - edit_entry (NULL); - return (FALSE); - } - return (TRUE); -} - - -static gint -bm_enter (GtkWidget * widget, GdkEventKey * event, gpointer data) -{ - if (event->type == GDK_KEY_PRESS) - { - if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) - { - edit_entry (NULL); - return (FALSE); - } - else if (event->keyval == GDK_KP_Delete || event->keyval == GDK_Delete) - { - delete_entry (NULL); - return (FALSE); - } - } - return (TRUE); -} - - -static void -new_folder_entry (gpointer data) -{ - MakeEditDialog (_("New Folder"), - _("Enter the name of the new folder to create"), NULL, 1, - NULL, gftp_dialog_button_create, - do_make_new, (gpointer) 0x1, NULL, NULL); -} - - -static void -new_item_entry (gpointer data) -{ - MakeEditDialog (_("New Folder"), - _("Enter the name of the new item to create"), NULL, 1, - NULL, gftp_dialog_button_create, - do_make_new, NULL, NULL, NULL); -} +#endif static void @@ -851,6 +571,353 @@ } +static void +new_folder_entry (gpointer data) +{ + MakeEditDialog (_("New Folder"), + _("Enter the name of the new folder to create"), NULL, 1, + NULL, gftp_dialog_button_create, + do_make_new, (gpointer) 0x1, NULL, NULL); +} + + +static void +new_item_entry (gpointer data) +{ + MakeEditDialog (_("New Folder"), + _("Enter the name of the new item to create"), NULL, 1, + NULL, gftp_dialog_button_create, + do_make_new, NULL, NULL, NULL); +} + + +static void +do_delete_entry (gftp_bookmarks * entry, gftp_dialog_data * ddata) +{ + gftp_bookmarks * tempentry, * delentry; + + g_hash_table_remove (new_bookmarks_htable, entry->path); + gtk_ctree_remove_node (GTK_CTREE (tree), entry->cnode); + if (entry->prev->children == entry) + entry->prev->children = entry->prev->children->next; + else + { + tempentry = entry->prev->children; + while (tempentry->next != entry) + tempentry = tempentry->next; + tempentry->next = entry->next; + } + + entry->prev = NULL; + entry->next = NULL; + tempentry = entry; + while (tempentry != NULL) + { + if (tempentry->path) + g_free (tempentry->path); + if (tempentry->hostname) + g_free (tempentry->hostname); + if (tempentry->remote_dir) + g_free (tempentry->remote_dir); + if (tempentry->user) + g_free (tempentry->user); + if (tempentry->pass) + g_free (tempentry->pass); + if (tempentry->sftpserv_path) + g_free (tempentry->sftpserv_path); + + if (tempentry->children != NULL) + { + tempentry = tempentry->children; + continue; + } + else if (tempentry->next == NULL && tempentry->prev != NULL) + { + delentry = tempentry->prev; + g_free (tempentry); + tempentry = delentry->next; + if (delentry != entry) + g_free (delentry); + } + else + tempentry = tempentry->next; + } + g_free (entry); +} + + +static void +delete_entry (gpointer data) +{ + gftp_bookmarks * entry; + char *tempstr, *pos; + + if (GTK_CLIST (tree)->selection == NULL) + return; + entry = + gtk_ctree_node_get_row_data (GTK_CTREE (tree), + GTK_CLIST (tree)->selection->data); + if (entry == NULL || entry->prev == NULL) + return; + + if (!entry->isfolder) + do_delete_entry (entry, NULL); + else + { + if ((pos = strrchr (entry->path, '/')) == NULL) + pos = entry->path; + else + pos++; + + tempstr = g_strdup_printf (_("Are you sure you want to erase the bookmark\n%s and all it's children?"), pos); + MakeYesNoDialog (_("Delete Bookmark"), tempstr, do_delete_entry, entry, + NULL, NULL); + g_free (tempstr); + } +} + + +static void +set_userpass_visible (GtkWidget * checkbutton, GtkWidget * entry) +{ + gtk_widget_set_sensitive (bm_useredit, !GTK_TOGGLE_BUTTON (anon_chk)->active); + gtk_widget_set_sensitive (bm_passedit, !GTK_TOGGLE_BUTTON (anon_chk)->active); + gtk_widget_set_sensitive (bm_acctedit, !GTK_TOGGLE_BUTTON (anon_chk)->active); +} + + +static void +build_bookmarks_tree (void) +{ + GdkPixmap * closedir_pixmap, * opendir_pixmap; + GdkBitmap * closedir_bitmap, * opendir_bitmap; + gftp_bookmarks * tempentry, * preventry; + char *pos, *prevpos, *text[2], *str; + GtkCTreeNode * parent; + + gftp_get_pixmap (tree, "open_dir.xpm", &opendir_pixmap, &opendir_bitmap); + gftp_get_pixmap (tree, "dir.xpm", &closedir_pixmap, &closedir_bitmap); + text[0] = text[1] = _("Bookmarks"); + parent = gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, text, 5, + closedir_pixmap, closedir_bitmap, + opendir_pixmap, opendir_bitmap, FALSE, TRUE); + gtk_ctree_node_set_row_data (GTK_CTREE (tree), parent, new_bookmarks); + new_bookmarks->cnode = parent; + + tempentry = new_bookmarks->children; + while (tempentry != NULL) + { + tempentry->cnode = NULL; + if (tempentry->children != NULL) + { + tempentry = tempentry->children; + continue; + } + else + { + pos = tempentry->path; + while ((pos = strchr (pos, '/')) != NULL) + { + *pos = '\0'; + str = g_malloc (strlen (tempentry->path) + 1); + strcpy (str, tempentry->path); + *pos = '/'; + preventry = g_hash_table_lookup (new_bookmarks_htable, str); + if (preventry->cnode == NULL) + { + if ((prevpos = strrchr (str, '/')) == NULL) + prevpos = str; + else + prevpos++; + text[0] = text[1] = prevpos; + preventry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree), + preventry->prev->cnode, NULL, text, + 5, closedir_pixmap, closedir_bitmap, + opendir_pixmap, opendir_bitmap, + FALSE, FALSE); + gtk_ctree_node_set_row_data (GTK_CTREE (tree), + preventry->cnode, preventry); + } + + g_free (str); + pos++; + } + } + + if ((pos = strrchr (tempentry->path, '/')) == NULL) + pos = tempentry->path; + else + pos++; + + text[0] = text[1] = pos; + tempentry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree), + tempentry->prev->cnode, NULL, + text, 5, NULL, NULL, NULL, NULL, FALSE, FALSE); + gtk_ctree_node_set_row_data (GTK_CTREE (tree), tempentry->cnode, + tempentry); + + while (tempentry->next == NULL && tempentry->prev != NULL) + tempentry = tempentry->prev; + tempentry = tempentry->next; + } +} + + +static void +clear_bookmarks_tree (void) +{ + gftp_bookmarks * tempentry; + + tempentry = new_bookmarks->children; + while (tempentry != NULL) + { + if (tempentry->children != NULL) + { + tempentry = tempentry->children; + continue; + } + while (tempentry->next == NULL && tempentry->prev != NULL) + { + gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode); + tempentry->cnode = NULL; + tempentry = tempentry->prev; + } + gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode); + tempentry->cnode = NULL; + tempentry = tempentry->next; + } +} + + +static void +entry_apply_changes (GtkWidget * widget, gftp_bookmarks * entry) +{ + char *pos, *newpath, tempchar, *tempstr, *origpath; + gftp_bookmarks * tempentry, * nextentry; + GtkWidget * tempwid; + const char *str; + int oldpathlen; + + oldpathlen = strlen (entry->path); + if ((pos = strrchr (entry->path, '/')) == NULL) + { + pos = entry->path; + tempchar = *entry->path; + *entry->path = '\0'; + } + else + { + tempchar = *pos; + *pos = '\0'; + } + origpath = newpath = g_strconcat (entry->path, "/", + gtk_entry_get_text (GTK_ENTRY (bm_pathedit)), NULL); + remove_double_slashes (newpath); + for (; *newpath == '/'; newpath++); + *pos = tempchar; + + str = gtk_entry_get_text (GTK_ENTRY (bm_hostedit)); + if (entry->hostname) + g_free (entry->hostname); + entry->hostname = g_malloc (strlen (str) + 1); + strcpy (entry->hostname, str); + + str = gtk_entry_get_text (GTK_ENTRY (bm_portedit)); + entry->port = strtol (str, NULL, 10); + + tempwid = gtk_menu_get_active (GTK_MENU (bm_protocol)); + str = gtk_object_get_user_data (GTK_OBJECT (tempwid)); + if (entry->protocol) + g_free (entry->protocol); + entry->protocol = g_malloc (strlen (str) + 1); + strcpy (entry->protocol, str); + + str = gtk_entry_get_text (GTK_ENTRY (bm_remotediredit)); + if (entry->remote_dir) + g_free (entry->remote_dir); + entry->remote_dir = g_malloc (strlen (str) + 1); + strcpy (entry->remote_dir, str); + + str = gtk_entry_get_text (GTK_ENTRY (bm_localdiredit)); + if (entry->local_dir) + g_free (entry->local_dir); + entry->local_dir = g_malloc (strlen (str) + 1); + strcpy (entry->local_dir, str); + + str = gtk_entry_get_text (GTK_ENTRY (bm_sftppath)); + if (entry->sftpserv_path) + g_free (entry->sftpserv_path); + if (strlen (str) > 0) + { + entry->sftpserv_path = g_malloc (strlen (str) + 1); + strcpy (entry->sftpserv_path, str); + } + else + entry->sftpserv_path = NULL; + + if (GTK_TOGGLE_BUTTON (anon_chk)->active) + str = "anonymous"; + else + str = gtk_entry_get_text (GTK_ENTRY (bm_useredit)); + if (entry->user) + g_free (entry->user); + entry->user = g_malloc (strlen (str) + 1); + strcpy (entry->user, str); + + if (GTK_TOGGLE_BUTTON (anon_chk)->active) + str = "@EMAIL@"; + else + str = gtk_entry_get_text (GTK_ENTRY (bm_passedit)); + if (entry->pass) + g_free (entry->pass); + entry->pass = g_malloc (strlen (str) + 1); + strcpy (entry->pass, str); + entry->save_password = *entry->pass != '\0'; + + if (GTK_TOGGLE_BUTTON (anon_chk)->active) + str = ""; + else + str = gtk_entry_get_text (GTK_ENTRY (bm_acctedit)); + if (entry->acct) + g_free (entry->acct); + entry->acct = g_malloc (strlen (str) + 1); + strcpy (entry->acct, str); + + if (strcmp (entry->path, newpath) != 0) + { + tempentry = entry; + nextentry = entry->next; + entry->next = NULL; + while (tempentry != NULL) + { + g_hash_table_remove (new_bookmarks_htable, tempentry->path); + tempstr = g_strconcat (newpath, "/", tempentry->path + oldpathlen, + NULL); + remove_double_slashes (tempstr); + g_free (tempentry->path); + tempentry->path = tempstr; + g_hash_table_insert (new_bookmarks_htable, tempentry->path, + tempentry); + if (tempentry->children != NULL) + { + tempentry = tempentry->children; + continue; + } + while (tempentry->next == NULL && tempentry != entry && + tempentry->prev != NULL) + tempentry = tempentry->prev; + + tempentry = tempentry->next; + } + entry->next = nextentry; + clear_bookmarks_tree (); + build_bookmarks_tree (); + } + + g_free (origpath); +} + + #if GTK_MAJOR_VERSION > 1 static void bmedit_action (GtkWidget * widget, gint response, gpointer user_data) @@ -1131,329 +1198,230 @@ } -static void -delete_entry (gpointer data) +static gint +bm_enter (GtkWidget * widget, GdkEventKey * event, gpointer data) { - gftp_bookmarks * entry; - char *tempstr, *pos; - - if (GTK_CLIST (tree)->selection == NULL) - return; - entry = - gtk_ctree_node_get_row_data (GTK_CTREE (tree), - GTK_CLIST (tree)->selection->data); - if (entry == NULL || entry->prev == NULL) - return; - - if (!entry->isfolder) - do_delete_entry (entry, NULL); - else - { - if ((pos = strrchr (entry->path, '/')) == NULL) - pos = entry->path; - else - pos++; - - tempstr = g_strdup_printf (_("Are you sure you want to erase the bookmark\n%s and all it's children?"), pos); - MakeYesNoDialog (_("Delete Bookmark"), tempstr, do_delete_entry, entry, - NULL, NULL); - g_free (tempstr); - } -} - - -static void -do_delete_entry (gftp_bookmarks * entry, gftp_dialog_data * ddata) -{ - gftp_bookmarks * tempentry, * delentry; - - g_hash_table_remove (new_bookmarks_htable, entry->path); - gtk_ctree_remove_node (GTK_CTREE (tree), entry->cnode); - if (entry->prev->children == entry) - entry->prev->children = entry->prev->children->next; - else + if (event->type == GDK_KEY_PRESS) { - tempentry = entry->prev->children; - while (tempentry->next != entry) - tempentry = tempentry->next; - tempentry->next = entry->next; + if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) + { + edit_entry (NULL); + return (FALSE); + } + else if (event->keyval == GDK_KP_Delete || event->keyval == GDK_Delete) + { + delete_entry (NULL); + return (FALSE); + } } - - entry->prev = NULL; - entry->next = NULL; - tempentry = entry; - while (tempentry != NULL) - { - if (tempentry->path) - g_free (tempentry->path); - if (tempentry->hostname) - g_free (tempentry->hostname); - if (tempentry->remote_dir) - g_free (tempentry->remote_dir); - if (tempentry->user) - g_free (tempentry->user); - if (tempentry->pass) - g_free (tempentry->pass); - if (tempentry->sftpserv_path) - g_free (tempentry->sftpserv_path); - - if (tempentry->children != NULL) - { - tempentry = tempentry->children; - continue; - } - else if (tempentry->next == NULL && tempentry->prev != NULL) - { - delentry = tempentry->prev; - g_free (tempentry); - tempentry = delentry->next; - if (delentry != entry) - g_free (delentry); - } - else - tempentry = tempentry->next; - } - g_free (entry); + return (TRUE); } static void -entry_apply_changes (GtkWidget * widget, gftp_bookmarks * entry) +after_move (GtkCTree * ctree, GtkCTreeNode * child, GtkCTreeNode * parent, + GtkCTreeNode * sibling, gpointer data) { - char *pos, *newpath, tempchar, *tempstr, *origpath; - gftp_bookmarks * tempentry, * nextentry; - GtkWidget * tempwid; - const char *str; - int oldpathlen; + + gftp_bookmarks * childentry, * siblingentry, * parententry, * tempentry; + char *tempstr, *pos, *stpos; + + childentry = gtk_ctree_node_get_row_data (ctree, child); + parententry = gtk_ctree_node_get_row_data (ctree, parent); + siblingentry = gtk_ctree_node_get_row_data (ctree, sibling); - oldpathlen = strlen (entry->path); - if ((pos = strrchr (entry->path, '/')) == NULL) + tempentry = childentry->prev->children; + if (tempentry == childentry) + childentry->prev->children = childentry->prev->children->next; + else { - pos = entry->path; - tempchar = *entry->path; - *entry->path = '\0'; + while (tempentry->next != childentry) + tempentry = tempentry->next; + tempentry->next = childentry->next; + } + childentry->prev = parententry; + if (!parententry->isfolder) + { + childentry->next = parententry->children; + parententry->children = childentry; + gtk_ctree_move (ctree, child, parententry->prev->cnode, + parententry->cnode); } else { - tempchar = *pos; - *pos = '\0'; - } - origpath = newpath = g_strconcat (entry->path, "/", - gtk_entry_get_text (GTK_ENTRY (bm_pathedit)), NULL); - remove_double_slashes (newpath); - for (; *newpath == '/'; newpath++); - *pos = tempchar; - - str = gtk_entry_get_text (GTK_ENTRY (bm_hostedit)); - if (entry->hostname) - g_free (entry->hostname); - entry->hostname = g_malloc (strlen (str) + 1); - strcpy (entry->hostname, str); - - str = gtk_entry_get_text (GTK_ENTRY (bm_portedit)); - entry->port = strtol (str, NULL, 10); - - tempwid = gtk_menu_get_active (GTK_MENU (bm_protocol)); - str = gtk_object_get_user_data (GTK_OBJECT (tempwid)); - if (entry->protocol) - g_free (entry->protocol); - entry->protocol = g_malloc (strlen (str) + 1); - strcpy (entry->protocol, str); - - str = gtk_entry_get_text (GTK_ENTRY (bm_remotediredit)); - if (entry->remote_dir) - g_free (entry->remote_dir); - entry->remote_dir = g_malloc (strlen (str) + 1); - strcpy (entry->remote_dir, str); - - str = gtk_entry_get_text (GTK_ENTRY (bm_localdiredit)); - if (entry->local_dir) - g_free (entry->local_dir); - entry->local_dir = g_malloc (strlen (str) + 1); - strcpy (entry->local_dir, str); + if (siblingentry == NULL || parententry->children == siblingentry) + { + childentry->next = parententry->children; + parententry->children = childentry; + } + else + { + tempentry = parententry->children; + while (tempentry->next != siblingentry) + tempentry = tempentry->next; + childentry->next = tempentry->next; + tempentry->next = childentry; + } - str = gtk_entry_get_text (GTK_ENTRY (bm_sftppath)); - if (entry->sftpserv_path) - g_free (entry->sftpserv_path); - if (strlen (str) > 0) - { - entry->sftpserv_path = g_malloc (strlen (str) + 1); - strcpy (entry->sftpserv_path, str); - } - else - entry->sftpserv_path = NULL; - - if (GTK_TOGGLE_BUTTON (anon_chk)->active) - str = "anonymous"; - else - str = gtk_entry_get_text (GTK_ENTRY (bm_useredit)); - if (entry->user) - g_free (entry->user); - entry->user = g_malloc (strlen (str) + 1); - strcpy (entry->user, str); - - if (GTK_TOGGLE_BUTTON (anon_chk)->active) - str = "@EMAIL@"; - else - str = gtk_entry_get_text (GTK_ENTRY (bm_passedit)); - if (entry->pass) - g_free (entry->pass); - entry->pass = g_malloc (strlen (str) + 1); - strcpy (entry->pass, str); - entry->save_password = *entry->pass != '\0'; - - if (GTK_TOGGLE_BUTTON (anon_chk)->active) - str = ""; - else - str = gtk_entry_get_text (GTK_ENTRY (bm_acctedit)); - if (entry->acct) - g_free (entry->acct); - entry->acct = g_malloc (strlen (str) + 1); - strcpy (entry->acct, str); - - if (strcmp (entry->path, newpath) != 0) - { - tempentry = entry; - nextentry = entry->next; - entry->next = NULL; + tempentry = childentry; while (tempentry != NULL) { g_hash_table_remove (new_bookmarks_htable, tempentry->path); - tempstr = g_strconcat (newpath, "/", tempentry->path + oldpathlen, - NULL); - remove_double_slashes (tempstr); + if ((pos = strrchr (tempentry->path, '/')) == NULL) + pos = tempentry->path; + else + pos++; + tempstr = g_strdup_printf ("%s/%s", tempentry->prev->path, pos); + for (stpos = tempstr; *stpos == '/'; stpos++); g_free (tempentry->path); - tempentry->path = tempstr; + tempentry->path = g_malloc (strlen (stpos) + 1); + strcpy (tempentry->path, stpos); + g_free (tempstr); g_hash_table_insert (new_bookmarks_htable, tempentry->path, tempentry); if (tempentry->children != NULL) + tempentry = tempentry->children; + else { - tempentry = tempentry->children; - continue; - } - while (tempentry->next == NULL && tempentry != entry && - tempentry->prev != NULL) - tempentry = tempentry->prev; - - tempentry = tempentry->next; - } - entry->next = nextentry; - clear_bookmarks_tree (); - build_bookmarks_tree (); - } - - g_free (origpath); -} - - -static void -set_userpass_visible (GtkWidget * checkbutton, GtkWidget * entry) -{ - gtk_widget_set_sensitive (bm_useredit, !GTK_TOGGLE_BUTTON (anon_chk)->active); - gtk_widget_set_sensitive (bm_passedit, !GTK_TOGGLE_BUTTON (anon_chk)->active); - gtk_widget_set_sensitive (bm_acctedit, !GTK_TOGGLE_BUTTON (anon_chk)->active); -} - - -static void -build_bookmarks_tree (void) -{ - GdkPixmap * closedir_pixmap, * opendir_pixmap; - GdkBitmap * closedir_bitmap, * opendir_bitmap; - gftp_bookmarks * tempentry, * preventry; - char *pos, *prevpos, *text[2], *str; - GtkCTreeNode * parent; - - gftp_get_pixmap (tree, "open_dir.xpm", &opendir_pixmap, &opendir_bitmap); - gftp_get_pixmap (tree, "dir.xpm", &closedir_pixmap, &closedir_bitmap); - text[0] = text[1] = _("Bookmarks"); - parent = gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, text, 5, - closedir_pixmap, closedir_bitmap, - opendir_pixmap, opendir_bitmap, FALSE, TRUE); - gtk_ctree_node_set_row_data (GTK_CTREE (tree), parent, new_bookmarks); - new_bookmarks->cnode = parent; - - tempentry = new_bookmarks->children; - while (tempentry != NULL) - { - tempentry->cnode = NULL; - if (tempentry->children != NULL) - { - tempentry = tempentry->children; - continue; - } - else - { - pos = tempentry->path; - while ((pos = strchr (pos, '/')) != NULL) - { - *pos = '\0'; - str = g_malloc (strlen (tempentry->path) + 1); - strcpy (str, tempentry->path); - *pos = '/'; - preventry = g_hash_table_lookup (new_bookmarks_htable, str); - if (preventry->cnode == NULL) + if (tempentry->next == NULL) { - if ((prevpos = strrchr (str, '/')) == NULL) - prevpos = str; + if (tempentry->prev == childentry) + break; else - prevpos++; - text[0] = text[1] = prevpos; - preventry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree), - preventry->prev->cnode, NULL, text, - 5, closedir_pixmap, closedir_bitmap, - opendir_pixmap, opendir_bitmap, - FALSE, FALSE); - gtk_ctree_node_set_row_data (GTK_CTREE (tree), - preventry->cnode, preventry); + { + while (tempentry->next == NULL + && tempentry->prev != NULL) + tempentry = tempentry->prev; + } } - - g_free (str); - pos++; + tempentry = tempentry->next; } } - - if ((pos = strrchr (tempentry->path, '/')) == NULL) - pos = tempentry->path; - else - pos++; - - text[0] = text[1] = pos; - tempentry->cnode = gtk_ctree_insert_node (GTK_CTREE (tree), - tempentry->prev->cnode, NULL, - text, 5, NULL, NULL, NULL, NULL, FALSE, FALSE); - gtk_ctree_node_set_row_data (GTK_CTREE (tree), tempentry->cnode, - tempentry); - - while (tempentry->next == NULL && tempentry->prev != NULL) - tempentry = tempentry->prev; - tempentry = tempentry->next; } } -static void -clear_bookmarks_tree (void) +static gint +bm_dblclick (GtkWidget * widget, GdkEventButton * event, gpointer data) { - gftp_bookmarks * tempentry; - - tempentry = new_bookmarks->children; - while (tempentry != NULL) + if (event->button == 3) + gtk_item_factory_popup (edit_factory, (guint) event->x_root, + (guint) event->y_root, 1, 0); + else if (event->type == GDK_2BUTTON_PRESS) { - if (tempentry->children != NULL) - { - tempentry = tempentry->children; - continue; - } - while (tempentry->next == NULL && tempentry->prev != NULL) - { - gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode); - tempentry->cnode = NULL; - tempentry = tempentry->prev; - } - gtk_ctree_remove_node (GTK_CTREE (tree), tempentry->cnode); - tempentry->cnode = NULL; - tempentry = tempentry->next; + edit_entry (NULL); + return (FALSE); } + return (TRUE); } + +void +edit_bookmarks (gpointer data) +{ + GtkWidget * dialog, * scroll; + GtkItemFactory * ifactory; + GtkItemFactoryEntry menu_items[] = { + {N_("/_File"), NULL, 0, 0, ""}, + {N_("/File/tearoff"), NULL, 0, 0, ""}, + {N_("/File/New Folder..."), NULL, new_folder_entry, 0, MN_(NULL)}, + {N_("/File/New Item..."), NULL, new_item_entry, 0, MS_(GTK_STOCK_NEW)}, + {N_("/File/Delete"), NULL, delete_entry, 0, MS_(GTK_STOCK_DELETE)}, + {N_("/File/Properties..."), NULL, edit_entry, 0, MS_(GTK_STOCK_PROPERTIES)}, + {N_("/File/sep"), NULL, 0, 0, ""}, + {N_("/File/Close"), NULL, gtk_widget_destroy, 0, MS_(GTK_STOCK_CLOSE)} + }; +#if GTK_MAJOR_VERSION == 1 + GtkWidget * tempwid; +#endif + + new_bookmarks = copy_bookmarks (bookmarks); + new_bookmarks_htable = build_bookmarks_hash_table (new_bookmarks); + +#if GTK_MAJOR_VERSION == 1 + dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Bookmarks")); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15); +#else + dialog = gtk_dialog_new_with_buttons (_("Edit Bookmarks"), NULL, 0, + GTK_STOCK_SAVE, + GTK_RESPONSE_OK, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); +#endif + gtk_window_set_wmclass (GTK_WINDOW(dialog), "Edit Bookmarks", "gFTP"); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); + gtk_widget_realize (dialog); + + if (gftp_icon != NULL) + { + gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap, + gftp_icon->bitmap); + gdk_window_set_icon_name (dialog->window, _("gFTP Icon")); + } + + /* FIXME - memory leak */ + ifactory = item_factory_new (GTK_TYPE_MENU_BAR, "", NULL, NULL); + create_item_factory (ifactory, 7, menu_items, NULL); + create_item_factory (ifactory, 1, menu_items + 7, dialog); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), ifactory->widget, + FALSE, FALSE, 0); + gtk_widget_show (ifactory->widget); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_widget_set_size_request (scroll, 150, 200); + + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), scroll, TRUE, TRUE, + 0); + gtk_container_border_width (GTK_CONTAINER (scroll), 3); + gtk_widget_show (scroll); + + /* FIXME - memory leak */ + edit_factory = item_factory_new (GTK_TYPE_MENU, "", NULL, "/File"); + + create_item_factory (edit_factory, 6, menu_items + 2, dialog); + + tree = gtk_ctree_new (1, 0); + gtk_clist_set_selection_mode (GTK_CLIST (tree), GTK_SELECTION_BROWSE); + gtk_clist_set_reorderable (GTK_CLIST (tree), 1); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), tree); + gtk_signal_connect_after (GTK_OBJECT (tree), "key_press_event", + GTK_SIGNAL_FUNC (bm_enter), (gpointer) tree); + gtk_signal_connect_after (GTK_OBJECT (tree), "tree_move", + GTK_SIGNAL_FUNC (after_move), NULL); + gtk_signal_connect_after (GTK_OBJECT (tree), "button_press_event", + GTK_SIGNAL_FUNC (bm_dblclick), (gpointer) tree); + gtk_widget_show (tree); + +#if GTK_MAJOR_VERSION == 1 + tempwid = gtk_button_new_with_label (_("OK")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, + TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (bm_apply_changes), NULL); + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_widget_show (tempwid); + + tempwid = gtk_button_new_with_label (_(" Cancel ")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, + TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (bm_close_dialog), (gpointer) dialog); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_widget_grab_focus (tempwid); + gtk_widget_show (tempwid); +#else + g_signal_connect (GTK_OBJECT (dialog), "response", + G_CALLBACK (editbm_action), NULL); +#endif + + gtk_widget_show (dialog); + + build_bookmarks_tree (); +} + diff -r eec25f215772 -r e5f6054590b5 src/gtk/chmod_dialog.c --- a/src/gtk/chmod_dialog.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/chmod_dialog.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,14 +20,114 @@ #include "gftp-gtk.h" static const char cvsid[] = "$Id$"; -static void dochmod ( GtkWidget * widget, - gftp_window_data * wdata ); -static void *do_chmod_thread ( void * data ); - static GtkWidget *suid, *sgid, *sticky, *ur, *uw, *ux, *gr, *gw, *gx, *or, *ow, *ox; static int mode; + +static void * +do_chmod_thread (void * data) +{ + GList * filelist, * templist; + gftp_window_data * wdata; + int success, num, sj; + gftp_file * tempfle; + + wdata = data; + wdata->request->user_data = (void *) 0x01; + + if (wdata->request->use_threads) + { + sj = sigsetjmp (jmp_environment, 1); + use_jmp_environment = 1; + } + else + sj = 0; + + success = 0; + if (sj == 0) + { + filelist = wdata->files; + templist = GTK_CLIST (wdata->listbox)->selection; + num = 0; + while (templist != NULL) + { + templist = get_next_selection (templist, &filelist, &num); + tempfle = filelist->data; + if (wdata->request->network_timeout > 0) + alarm (wdata->request->network_timeout); + if (gftp_chmod (wdata->request, tempfle->file, mode) == 0) + success = 1; + if (!GFTP_IS_CONNECTED (wdata->request)) + break; + } + alarm (0); + } + else + { + gftp_disconnect (wdata->request); + wdata->request->logging_function (gftp_logging_error, + wdata->request->user_data, + _("Operation canceled\n")); + } + + if (wdata->request->use_threads) + use_jmp_environment = 0; + + wdata->request->user_data = NULL; + wdata->request->stopable = 0; + return ((void *) success); +} + + +static void +dochmod (GtkWidget * widget, gftp_window_data * wdata) +{ + int cur; + + mode = 0; + if (GTK_TOGGLE_BUTTON (suid)->active) + mode += 4; + if (GTK_TOGGLE_BUTTON (sgid)->active) + mode += 2; + if (GTK_TOGGLE_BUTTON (sticky)->active) + mode += 1; + + cur = 0; + if (GTK_TOGGLE_BUTTON (ur)->active) + cur += 4; + if (GTK_TOGGLE_BUTTON (uw)->active) + cur += 2; + if (GTK_TOGGLE_BUTTON (ux)->active) + cur += 1; + mode = mode * 10 + cur; + + cur = 0; + if (GTK_TOGGLE_BUTTON (gr)->active) + cur += 4; + if (GTK_TOGGLE_BUTTON (gw)->active) + cur += 2; + if (GTK_TOGGLE_BUTTON (gx)->active) + cur += 1; + mode = mode * 10 + cur; + + cur = 0; + if (GTK_TOGGLE_BUTTON (or)->active) + cur += 4; + if (GTK_TOGGLE_BUTTON (ow)->active) + cur += 2; + if (GTK_TOGGLE_BUTTON (ox)->active) + cur += 1; + mode = mode * 10 + cur; + + if (check_reconnect (wdata) < 0) + return; + + if ((int) generic_thread (do_chmod_thread, wdata)) + refresh (wdata); +} + + #if GTK_MAJOR_VERSION > 1 static void chmod_action (GtkWidget * widget, gint response, gpointer wdata) @@ -239,106 +339,3 @@ gtk_widget_show (dialog); } - -static void -dochmod (GtkWidget * widget, gftp_window_data * wdata) -{ - int cur; - - mode = 0; - if (GTK_TOGGLE_BUTTON (suid)->active) - mode += 4; - if (GTK_TOGGLE_BUTTON (sgid)->active) - mode += 2; - if (GTK_TOGGLE_BUTTON (sticky)->active) - mode += 1; - - cur = 0; - if (GTK_TOGGLE_BUTTON (ur)->active) - cur += 4; - if (GTK_TOGGLE_BUTTON (uw)->active) - cur += 2; - if (GTK_TOGGLE_BUTTON (ux)->active) - cur += 1; - mode = mode * 10 + cur; - - cur = 0; - if (GTK_TOGGLE_BUTTON (gr)->active) - cur += 4; - if (GTK_TOGGLE_BUTTON (gw)->active) - cur += 2; - if (GTK_TOGGLE_BUTTON (gx)->active) - cur += 1; - mode = mode * 10 + cur; - - cur = 0; - if (GTK_TOGGLE_BUTTON (or)->active) - cur += 4; - if (GTK_TOGGLE_BUTTON (ow)->active) - cur += 2; - if (GTK_TOGGLE_BUTTON (ox)->active) - cur += 1; - mode = mode * 10 + cur; - - if (check_reconnect (wdata) < 0) - return; - - if ((int) generic_thread (do_chmod_thread, wdata)) - refresh (wdata); -} - - -static void * -do_chmod_thread (void * data) -{ - GList * filelist, * templist; - gftp_window_data * wdata; - int success, num, sj; - gftp_file * tempfle; - - wdata = data; - wdata->request->user_data = (void *) 0x01; - - if (wdata->request->use_threads) - { - sj = sigsetjmp (jmp_environment, 1); - use_jmp_environment = 1; - } - else - sj = 0; - - success = 0; - if (sj == 0) - { - filelist = wdata->files; - templist = GTK_CLIST (wdata->listbox)->selection; - num = 0; - while (templist != NULL) - { - templist = get_next_selection (templist, &filelist, &num); - tempfle = filelist->data; - if (wdata->request->network_timeout > 0) - alarm (wdata->request->network_timeout); - if (gftp_chmod (wdata->request, tempfle->file, mode) == 0) - success = 1; - if (!GFTP_IS_CONNECTED (wdata->request)) - break; - } - alarm (0); - } - else - { - gftp_disconnect (wdata->request); - wdata->request->logging_function (gftp_logging_error, - wdata->request->user_data, - _("Operation canceled\n")); - } - - if (wdata->request->use_threads) - use_jmp_environment = 0; - - wdata->request->user_data = NULL; - wdata->request->stopable = 0; - return ((void *) success); -} - diff -r eec25f215772 -r e5f6054590b5 src/gtk/delete_dialog.c --- a/src/gtk/delete_dialog.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/delete_dialog.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,13 +20,156 @@ #include "gftp-gtk.h" static const char cvsid[] = "$Id$"; -static void askdel ( gftp_transfer * transfer ); -static void yesCB ( gftp_transfer * transfer, - gftp_dialog_data * ddata ); -static void * do_delete_thread ( void *data ); -static void delete_purge_cache ( gpointer key, - gpointer value, - gpointer user_data ); +static void +delete_purge_cache (gpointer key, gpointer value, gpointer user_data) +{ + gftp_request * request; + char *olddir; + + request = user_data; + olddir = request->directory; + request->directory = key; + gftp_delete_cache_entry (request, 0); + request->directory = olddir; + g_free (key); +} + + +static void * +do_delete_thread (void *data) +{ + gftp_transfer * transfer; + char *pos, *tempstr; + gftp_file * tempfle; + GHashTable * rmhash; + GList * templist; + int success, sj; + + transfer = data; + transfer->fromreq->user_data = (void *) 0x01; + + if (transfer->fromreq->use_threads) + { + sj = sigsetjmp (jmp_environment, 1); + use_jmp_environment = 1; + } + else + sj = 0; + + if (sj == 0) + { + for (templist = transfer->files; templist->next != NULL; + templist = templist->next); + + rmhash = g_hash_table_new (string_hash_function, string_hash_compare); + while (1) + { + tempfle = templist->data; + if (tempfle->isdir) + success = gftp_remove_directory (transfer->fromreq, tempfle->file); + else + success = gftp_remove_file (transfer->fromreq, tempfle->file); + + if (success == 0 && (pos = strrchr (tempfle->file, '/'))) + { + *pos = '\0'; + if (g_hash_table_lookup (rmhash, tempfle->file) == NULL) + { + tempstr = g_strconcat (tempfle->file, NULL); + g_hash_table_insert (rmhash, tempstr, NULL); + } + *pos = '/'; + } + + if (templist == transfer->files || + !GFTP_IS_CONNECTED (transfer->fromreq)) + break; + templist = templist->prev; + } + + g_hash_table_foreach (rmhash, delete_purge_cache, transfer->fromreq); + g_hash_table_destroy (rmhash); + } + else + { + gftp_disconnect (transfer->fromreq); + transfer->fromreq->logging_function (gftp_logging_error, + transfer->fromreq->user_data, + _("Operation canceled\n")); + } + + transfer->fromreq->user_data = NULL; + transfer->fromreq->stopable = 0; + + if (transfer->fromreq->use_threads) + use_jmp_environment = 0; + + return (NULL); +} + + +static void +yesCB (gftp_transfer * transfer, gftp_dialog_data * ddata) +{ + gftp_window_data * wdata; + void * ret; + + g_return_if_fail (transfer != NULL); + g_return_if_fail (transfer->files != NULL); + + wdata = transfer->fromwdata; + if (check_reconnect (wdata) < 0) + return; + + gtk_clist_freeze (GTK_CLIST (wdata->listbox)); + swap_socks (transfer->fromreq, wdata->request); + if (wdata->request->use_threads) + { + wdata->request->stopable = 1; + transfer->fromreq->stopable = 1; + gtk_widget_set_sensitive (stop_btn, 1); + pthread_create (&wdata->tid, NULL, do_delete_thread, transfer); + + while (transfer->fromreq->stopable) + { + GDK_THREADS_LEAVE (); +#if GTK_MAJOR_VERSION == 1 + g_main_iteration (TRUE); +#else + g_main_context_iteration (NULL, TRUE); +#endif + } + + gtk_widget_set_sensitive (stop_btn, 0); + pthread_join (wdata->tid, &ret); + wdata->request->stopable = 0; + } + else + ret = do_delete_thread (transfer); + swap_socks (wdata->request, transfer->fromreq); + free_tdata (transfer); + + if (!GFTP_IS_CONNECTED (wdata->request)) + disconnect (wdata); + else + refresh (wdata); + + gtk_clist_thaw (GTK_CLIST (wdata->listbox)); +} + + +static void +askdel (gftp_transfer * transfer) +{ + char *tempstr; + + tempstr = g_strdup_printf (_("Are you sure you want to delete these %ld files and %ld directories"), transfer->numfiles, transfer->numdirs); + + MakeYesNoDialog (_("Delete Files/Directories"), tempstr, + yesCB, transfer, NULL, NULL); + g_free (tempstr); +} + void delete_dialog (gpointer data) @@ -115,153 +258,3 @@ } -static void -askdel (gftp_transfer * transfer) -{ - char *tempstr; - - tempstr = g_strdup_printf (_("Are you sure you want to delete these %ld files and %ld directories"), transfer->numfiles, transfer->numdirs); - - MakeYesNoDialog (_("Delete Files/Directories"), tempstr, - yesCB, transfer, NULL, NULL); - g_free (tempstr); -} - - -static void -yesCB (gftp_transfer * transfer, gftp_dialog_data * ddata) -{ - gftp_window_data * wdata; - void * ret; - - g_return_if_fail (transfer != NULL); - g_return_if_fail (transfer->files != NULL); - - wdata = transfer->fromwdata; - if (check_reconnect (wdata) < 0) - return; - - gtk_clist_freeze (GTK_CLIST (wdata->listbox)); - swap_socks (transfer->fromreq, wdata->request); - if (wdata->request->use_threads) - { - wdata->request->stopable = 1; - transfer->fromreq->stopable = 1; - gtk_widget_set_sensitive (stop_btn, 1); - pthread_create (&wdata->tid, NULL, do_delete_thread, transfer); - - while (transfer->fromreq->stopable) - { - GDK_THREADS_LEAVE (); -#if GTK_MAJOR_VERSION == 1 - g_main_iteration (TRUE); -#else - g_main_context_iteration (NULL, TRUE); -#endif - } - - gtk_widget_set_sensitive (stop_btn, 0); - pthread_join (wdata->tid, &ret); - wdata->request->stopable = 0; - } - else - ret = do_delete_thread (transfer); - swap_socks (wdata->request, transfer->fromreq); - free_tdata (transfer); - - if (!GFTP_IS_CONNECTED (wdata->request)) - disconnect (wdata); - else - refresh (wdata); - - gtk_clist_thaw (GTK_CLIST (wdata->listbox)); -} - - -static void * -do_delete_thread (void *data) -{ - gftp_transfer * transfer; - char *pos, *tempstr; - gftp_file * tempfle; - GHashTable * rmhash; - GList * templist; - int success, sj; - - transfer = data; - transfer->fromreq->user_data = (void *) 0x01; - - if (transfer->fromreq->use_threads) - { - sj = sigsetjmp (jmp_environment, 1); - use_jmp_environment = 1; - } - else - sj = 0; - - if (sj == 0) - { - for (templist = transfer->files; templist->next != NULL; - templist = templist->next); - - rmhash = g_hash_table_new (string_hash_function, string_hash_compare); - while (1) - { - tempfle = templist->data; - if (tempfle->isdir) - success = gftp_remove_directory (transfer->fromreq, tempfle->file); - else - success = gftp_remove_file (transfer->fromreq, tempfle->file); - - if (success == 0 && (pos = strrchr (tempfle->file, '/'))) - { - *pos = '\0'; - if (g_hash_table_lookup (rmhash, tempfle->file) == NULL) - { - tempstr = g_strconcat (tempfle->file, NULL); - g_hash_table_insert (rmhash, tempstr, NULL); - } - *pos = '/'; - } - - if (templist == transfer->files || - !GFTP_IS_CONNECTED (transfer->fromreq)) - break; - templist = templist->prev; - } - - g_hash_table_foreach (rmhash, delete_purge_cache, transfer->fromreq); - g_hash_table_destroy (rmhash); - } - else - { - gftp_disconnect (transfer->fromreq); - transfer->fromreq->logging_function (gftp_logging_error, - transfer->fromreq->user_data, - _("Operation canceled\n")); - } - - transfer->fromreq->user_data = NULL; - transfer->fromreq->stopable = 0; - - if (transfer->fromreq->use_threads) - use_jmp_environment = 0; - - return (NULL); -} - - -static void -delete_purge_cache (gpointer key, gpointer value, gpointer user_data) -{ - gftp_request * request; - char *olddir; - - request = user_data; - olddir = request->directory; - request->directory = key; - gftp_delete_cache_entry (request, 0); - request->directory = olddir; - g_free (key); -} - diff -r eec25f215772 -r e5f6054590b5 src/gtk/dnd.c --- a/src/gtk/dnd.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/dnd.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,9 +20,122 @@ #include "gftp-gtk.h" static const char cvsid[] = "$Id$"; -static int dnd_remote_file ( char *url, - GList ** transfers, - gftp_window_data * wdata ); + +static int +dnd_remote_file (char *url, GList ** transfers, gftp_window_data * wdata) +{ + gftp_request * current_ftpdata; + gftp_window_data * fromwdata; + gftp_transfer * tdata; + gftp_file * newfle; + GList * templist; + char *str, *pos; + int i; + + newfle = g_malloc0 (sizeof (*newfle)); + newfle->shown = 1; + if (url[strlen (url) - 1] == '/') + { + newfle->isdir = 1; + url[strlen (url) - 1] = '\0'; + } + + current_ftpdata = gftp_request_new (); + current_ftpdata->logging_function = ftp_log; + + if (gftp_parse_url (current_ftpdata, url) != 0) + { + ftp_log (gftp_logging_misc, NULL, + _("Drag-N-Drop: Ignoring url %s: Not a valid url\n"), url); + gftp_request_destroy (current_ftpdata); + free_fdata (newfle); + return (0); + } + + if ((str = GFTP_GET_DIRECTORY (current_ftpdata)) != NULL) + { + if ((pos = strrchr (str, '/')) == NULL) + pos = str; + else pos++; + *(pos - 1) = '\0'; + i = 1; + } + else + { + pos = str = GFTP_GET_DIRECTORY (current_ftpdata); + i = 0; + } + + if (compare_request (current_ftpdata, wdata->request, 1)) + return (0); + + if (i) + { + *(pos - 1) = '/'; + newfle->file = g_malloc (strlen (str) + 1); + strcpy (newfle->file, str); + *(pos - 1) = '\0'; + } + else + { + newfle->file = g_malloc (strlen (str) + 1); + strcpy (newfle->file, str); + } + + newfle->destfile = g_strconcat (GFTP_GET_DIRECTORY (wdata->request), + "/", pos, NULL); + newfle->ascii = gftp_get_file_transfer_mode (newfle->file, + wdata->request->data_type) == GFTP_TYPE_ASCII; + + tdata = NULL; + templist = *transfers; + while (templist != NULL) + { + tdata = templist->data; + if (compare_request (tdata->fromreq, current_ftpdata, 1)) + break; + templist = templist->next; + } + + if (tdata == NULL) + { + tdata = g_malloc0 (sizeof (*tdata)); + tdata->towdata = wdata == &window1 ? &window1 : &window2; + fromwdata = wdata == &window1 ? &window2 : &window1; + if (fromwdata->request != NULL && + compare_request (fromwdata->request, current_ftpdata, 1)) + { + if (fromwdata->request->password != NULL) + gftp_set_password (current_ftpdata, fromwdata->request->password); + tdata->fromwdata = fromwdata; + } + tdata->fromreq = current_ftpdata; + tdata->toreq = gftp_request_new (); + tdata->toreq->logging_function = ftp_log; + tdata->toreq = copy_request (wdata->request); + *transfers = g_list_append (*transfers, tdata); + } + else + gftp_request_destroy (current_ftpdata); + + if (newfle->isdir) + { +/* FIXME - need to fix this + add_entire_directory (tdata, newfle, + GFTP_GET_DIRECTORY (tdata->fromhdata->ftpdata), + GFTP_GET_DIRECTORY (tdata->tohdata->ftpdata), + tdata->fromhdata->ftpdata); +*/ + } + else + { + tdata->files = g_list_append (tdata->files, newfle); + if (tdata->curfle == NULL) + tdata->curfle = tdata->files; + } + return (1); +} + void openurl_get_drag_data (GtkWidget * widget, GdkDragContext * context, gint x, @@ -184,119 +297,3 @@ gtk_drag_finish (context, finish_drag, FALSE, clk_time); } - -static int -dnd_remote_file (char *url, GList ** transfers, gftp_window_data * wdata) -{ - gftp_request * current_ftpdata; - gftp_window_data * fromwdata; - gftp_transfer * tdata; - gftp_file * newfle; - GList * templist; - char *str, *pos; - int i; - - newfle = g_malloc0 (sizeof (*newfle)); - newfle->shown = 1; - if (url[strlen (url) - 1] == '/') - { - newfle->isdir = 1; - url[strlen (url) - 1] = '\0'; - } - - current_ftpdata = gftp_request_new (); - current_ftpdata->logging_function = ftp_log; - - if (gftp_parse_url (current_ftpdata, url) != 0) - { - ftp_log (gftp_logging_misc, NULL, - _("Drag-N-Drop: Ignoring url %s: Not a valid url\n"), url); - gftp_request_destroy (current_ftpdata); - free_fdata (newfle); - return (0); - } - - if ((str = GFTP_GET_DIRECTORY (current_ftpdata)) != NULL) - { - if ((pos = strrchr (str, '/')) == NULL) - pos = str; - else pos++; - *(pos - 1) = '\0'; - i = 1; - } - else - { - pos = str = GFTP_GET_DIRECTORY (current_ftpdata); - i = 0; - } - - if (compare_request (current_ftpdata, wdata->request, 1)) - return (0); - - if (i) - { - *(pos - 1) = '/'; - newfle->file = g_malloc (strlen (str) + 1); - strcpy (newfle->file, str); - *(pos - 1) = '\0'; - } - else - { - newfle->file = g_malloc (strlen (str) + 1); - strcpy (newfle->file, str); - } - - newfle->destfile = g_strconcat (GFTP_GET_DIRECTORY (wdata->request), - "/", pos, NULL); - newfle->ascii = gftp_get_file_transfer_mode (newfle->file, - wdata->request->data_type) == GFTP_TYPE_ASCII; - - tdata = NULL; - templist = *transfers; - while (templist != NULL) - { - tdata = templist->data; - if (compare_request (tdata->fromreq, current_ftpdata, 1)) - break; - templist = templist->next; - } - - if (tdata == NULL) - { - tdata = g_malloc0 (sizeof (*tdata)); - tdata->towdata = wdata == &window1 ? &window1 : &window2; - fromwdata = wdata == &window1 ? &window2 : &window1; - if (fromwdata->request != NULL && - compare_request (fromwdata->request, current_ftpdata, 1)) - { - if (fromwdata->request->password != NULL) - gftp_set_password (current_ftpdata, fromwdata->request->password); - tdata->fromwdata = fromwdata; - } - tdata->fromreq = current_ftpdata; - tdata->toreq = gftp_request_new (); - tdata->toreq->logging_function = ftp_log; - tdata->toreq = copy_request (wdata->request); - *transfers = g_list_append (*transfers, tdata); - } - else - gftp_request_destroy (current_ftpdata); - - if (newfle->isdir) - { -/* FIXME - need to fix this - add_entire_directory (tdata, newfle, - GFTP_GET_DIRECTORY (tdata->fromhdata->ftpdata), - GFTP_GET_DIRECTORY (tdata->tohdata->ftpdata), - tdata->fromhdata->ftpdata); -*/ - } - else - { - tdata->files = g_list_append (tdata->files, newfle); - if (tdata->curfle == NULL) - tdata->curfle = tdata->files; - } - return (1); -} - diff -r eec25f215772 -r e5f6054590b5 src/gtk/gftp-gtk.c --- a/src/gtk/gftp-gtk.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/gftp-gtk.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,41 +20,6 @@ #include "gftp-gtk.h" static const char cvsid[] = "$Id$"; -static gint delete_event ( GtkWidget * widget, - GdkEvent * event, - gpointer data ); -static void destroy ( GtkWidget * widget, - gpointer data ); -static RETSIGTYPE sig_child ( int signo ); -static GtkWidget * CreateFTPWindows ( GtkWidget * ui ); -static GtkWidget * CreateMenus ( GtkWidget * parent ); -static GtkWidget * CreateToolbar ( GtkWidget * parent ); -static void doexit ( GtkWidget * widget, - gpointer data ); -static int get_column ( GtkCListColumn * col ); -static void init_gftp ( int argc, - char *argv[], - GtkWidget * parent ); -static void menu_exit ( GtkWidget * widget, - gpointer data ); -static GtkWidget * CreateFTPWindow ( gftp_window_data * wdata, - int width, - int columns[6] ); -static void setup_column ( GtkWidget * listbox, - int column, - int width ); -static gint menu_mouse_click ( GtkWidget * widget, - GdkEventButton * event, - gpointer data ); -static gint list_dblclick ( GtkWidget * widget, - GdkEventButton * event, - gpointer data ); -static void list_doaction ( gftp_window_data * wdata ); -static gint list_enter ( GtkWidget * widget, - GdkEventKey * event, - gpointer data ); -static void chfunc ( gpointer data ); - static GtkItemFactory *log_factory, *dl_factory; static GtkWidget * local_frame, * remote_frame, * log_table, * transfer_scroll, * openurl_btn; @@ -77,86 +42,46 @@ sigjmp_buf jmp_environment; volatile int use_jmp_environment = 0; - -int -main (int argc, char **argv) +static int +get_column (GtkCListColumn * col) { - GtkWidget *window, *ui; - -#ifdef HAVE_GETTEXT - setlocale (LC_ALL, ""); - bindtextdomain ("gftp", LOCALE_DIR); -#if GTK_MAJOR_VERSION > 1 - bind_textdomain_codeset ("gftp", "UTF-8"); -#endif - textdomain ("gftp"); -#endif - - g_thread_init (NULL); - gtk_set_locale (); - gtk_init (&argc, &argv); + if (col->auto_resize) + return (0); + else if (!col->visible) + return (-1); + else + return (col->width); +} - signal (SIGCHLD, sig_child); - signal (SIGPIPE, SIG_IGN); - signal (SIGALRM, signal_handler); - signal (SIGINT, signal_handler); - - graphic_hash_table = g_hash_table_new (string_hash_function, string_hash_compare); - gftp_read_config_file (argv, 1); - if (gftp_parse_command_line (&argc, &argv) != 0) - exit (0); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC (delete_event), NULL); - gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC (destroy), NULL); - gtk_window_set_title (GTK_WINDOW (window), version); - gtk_window_set_wmclass (GTK_WINDOW(window), "main", "gFTP"); - gtk_widget_set_name (window, version); - gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE); - gtk_widget_realize (window); - gftp_icon = open_xpm (window, "gftp.xpm"); - if (gftp_icon != NULL) - { - gdk_window_set_icon (window->window, NULL, gftp_icon->pixmap, - gftp_icon->bitmap); - gdk_window_set_icon_name (window->window, _("gFTP Icon")); - } - - other_wdata = &window1; - current_wdata = &window2; - ui = CreateFTPWindows (window); - gtk_container_add (GTK_CONTAINER (window), ui); - gtk_widget_show (window); +static void +doexit (GtkWidget * widget, gpointer data) +{ + listbox_local_width = GTK_WIDGET (local_frame)->allocation.width; + listbox_remote_width = GTK_WIDGET (remote_frame)->allocation.width; + listbox_file_height = GTK_WIDGET (remote_frame)->allocation.height; + log_height = GTK_WIDGET (log_table)->allocation.height; + transfer_height = GTK_WIDGET (transfer_scroll)->allocation.height; - ftp_log (gftp_logging_misc, NULL, - "%s, Copyright (C) 1998-2002 Brian Masney <", version); - ftp_log (gftp_logging_recv, NULL, "masneyb@gftp.org"); - ftp_log (gftp_logging_misc, NULL, - _(">. If you have any questions, comments, or suggestions about this program, please feel free to email them to me. You can always find out the latest news about gFTP from my website at http://www.gftp.org/\n")); - ftp_log (gftp_logging_misc, NULL, - _("gFTP comes with ABSOLUTELY NO WARRANTY; for details, see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; for details, see the COPYING file\n")); + local_columns[0] = get_column (>K_CLIST (window1.listbox)->column[1]); + local_columns[1] = get_column (>K_CLIST (window1.listbox)->column[2]); + local_columns[2] = get_column (>K_CLIST (window1.listbox)->column[3]); + local_columns[3] = get_column (>K_CLIST (window1.listbox)->column[4]); + local_columns[4] = get_column (>K_CLIST (window1.listbox)->column[5]); + local_columns[5] = get_column (>K_CLIST (window1.listbox)->column[6]); - gtk_timeout_add (1000, update_downloads, NULL); - gftp_protocols[GFTP_LOCAL_NUM].init (window1.request); - if (startup_directory != NULL && *startup_directory != '\0') - gftp_set_directory (window1.request, startup_directory); - gftp_connect (window1.request); - ftp_list_files (&window1, 0); + remote_columns[0] = get_column (>K_CLIST (window2.listbox)->column[1]); + remote_columns[1] = get_column (>K_CLIST (window2.listbox)->column[2]); + remote_columns[2] = get_column (>K_CLIST (window2.listbox)->column[3]); + remote_columns[3] = get_column (>K_CLIST (window2.listbox)->column[4]); + remote_columns[4] = get_column (>K_CLIST (window2.listbox)->column[5]); + remote_columns[5] = get_column (>K_CLIST (window2.listbox)->column[6]); - /* On the remote window, even though we aren't connected, draw the sort - icon on that side */ - sortrows (GTK_CLIST (window2.listbox), *window2.sortcol, &window2); + file_trans_column = get_column (>K_CLIST (dlwdw)->column[0]); - init_gftp (argc, argv, window); - gftp_is_started = 1; - - GDK_THREADS_ENTER (); - gtk_main (); - GDK_THREADS_LEAVE (); - return (0); + gftp_write_config_file (); + gftp_clear_cache_files (); + exit (0); } @@ -188,177 +113,18 @@ } -static GtkWidget * -CreateFTPWindows (GtkWidget * ui) +static void +menu_exit (GtkWidget * widget, gpointer data) { - GtkWidget *box, *dlbox, *winpane, *dlpane, *logpane, *mainvbox, *tempwid, - *button; - char *dltitles[2]; -#if GTK_MAJOR_VERSION > 1 - GtkTextBuffer * textbuf; - GtkTextIter iter; - GtkTextTag *tag; - GdkColor fore; -#endif - - memset (&window1, 0, sizeof (window1)); - memset (&window2, 0, sizeof (window2)); - window1.history = &localhistory; - window1.histlen = &localhistlen; - window2.history = &remotehistory; - window2.histlen = &remotehistlen; - - mainvbox = gtk_vbox_new (FALSE, 0); - - tempwid = CreateMenus (ui); - gtk_box_pack_start (GTK_BOX (mainvbox), tempwid, FALSE, FALSE, 0); - - tempwid = CreateToolbar (ui); - gtk_box_pack_start (GTK_BOX (mainvbox), tempwid, FALSE, FALSE, 0); - - winpane = gtk_hpaned_new (); - - box = gtk_hbox_new (FALSE, 0); - - local_frame = CreateFTPWindow (&window1, listbox_local_width, local_columns); - window1.sortcol = &local_sortcol; - window1.sortasds = &local_sortasds; - gtk_box_pack_start (GTK_BOX (box), local_frame, TRUE, TRUE, 0); - - dlbox = gtk_vbox_new (FALSE, 0); - gtk_container_border_width (GTK_CONTAINER (dlbox), 5); - gtk_box_pack_start (GTK_BOX (box), dlbox, FALSE, FALSE, 0); - -#if GTK_MAJOR_VERSION == 1 - tempwid = toolbar_pixmap (ui, "right.xpm"); -#else - tempwid = gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, - GTK_ICON_SIZE_SMALL_TOOLBAR); -#endif - - button = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (dlbox), button, TRUE, FALSE, 0); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (put_files), NULL); - gtk_container_add (GTK_CONTAINER (button), tempwid); - -#if GTK_MAJOR_VERSION == 1 - tempwid = toolbar_pixmap (ui, "left.xpm"); -#else - tempwid = gtk_image_new_from_stock (GTK_STOCK_GO_BACK, - GTK_ICON_SIZE_SMALL_TOOLBAR); -#endif - - button = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (dlbox), button, TRUE, FALSE, 0); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (get_files), NULL); - gtk_container_add (GTK_CONTAINER (button), tempwid); - - gtk_paned_pack1 (GTK_PANED (winpane), box, 1, 1); - - remote_frame = CreateFTPWindow (&window2, listbox_remote_width, - remote_columns); - window2.sortcol = &remote_sortcol; - window2.sortasds = &remote_sortasds; - gtk_paned_pack2 (GTK_PANED (winpane), remote_frame, 1, 1); - - dlpane = gtk_vpaned_new (); - gtk_paned_pack1 (GTK_PANED (dlpane), winpane, 1, 1); - - transfer_scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_set_size_request (transfer_scroll, -1, transfer_height); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (transfer_scroll), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + if (!delete_event (widget, NULL, data)) + doexit (widget, data); +} - dltitles[0] = _("Filename"); - dltitles[1] = _("Progress"); - dlwdw = gtk_ctree_new_with_titles (2, 0, dltitles); - gtk_clist_set_selection_mode (GTK_CLIST (dlwdw), GTK_SELECTION_SINGLE); - gtk_clist_set_reorderable (GTK_CLIST (dlwdw), 0); - if (file_trans_column == 0) - gtk_clist_set_column_auto_resize (GTK_CLIST (dlwdw), 0, TRUE); - else - gtk_clist_set_column_width (GTK_CLIST (dlwdw), 0, file_trans_column); - - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (transfer_scroll), dlwdw); - gtk_signal_connect (GTK_OBJECT (dlwdw), "button_press_event", - GTK_SIGNAL_FUNC (menu_mouse_click), (gpointer) dl_factory); - gtk_paned_pack2 (GTK_PANED (dlpane), transfer_scroll, 1, 1); - - logpane = gtk_vpaned_new (); - gtk_paned_pack1 (GTK_PANED (logpane), dlpane, 1, 1); - - log_table = gtk_table_new (1, 2, FALSE); - gtk_widget_set_size_request (log_table, -1, log_height); - -#if GTK_MAJOR_VERSION == 1 - logwdw = gtk_text_new (NULL, NULL); - - gtk_text_set_editable (GTK_TEXT (logwdw), FALSE); - gtk_text_set_word_wrap (GTK_TEXT (logwdw), TRUE); - - gtk_table_attach (GTK_TABLE (log_table), logwdw, 0, 1, 0, 1, - GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, - 0, 0); - gtk_signal_connect (GTK_OBJECT (logwdw), "button_press_event", - GTK_SIGNAL_FUNC (menu_mouse_click), - (gpointer) log_factory); - - tempwid = gtk_vscrollbar_new (GTK_TEXT (logwdw)->vadj); - gtk_table_attach (GTK_TABLE (log_table), tempwid, 1, 2, 0, 1, - GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0); - logwdw_vadj = GTK_TEXT (logwdw)->vadj; -#else - logwdw = gtk_text_view_new (); - gtk_text_view_set_editable (GTK_TEXT_VIEW (logwdw), FALSE); - gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (logwdw), FALSE); - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (logwdw), GTK_WRAP_WORD); - - textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (logwdw)); - - tag = gtk_text_buffer_create_tag (textbuf, "send", NULL); - fore.red = send_color.red; - fore.green = send_color.green; - fore.blue = send_color.blue; - g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); - - tag = gtk_text_buffer_create_tag (textbuf, "recv", NULL); - fore.red = recv_color.red; - fore.green = recv_color.green; - fore.blue = recv_color.blue; - g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); - - tag = gtk_text_buffer_create_tag (textbuf, "error", NULL); - fore.red = error_color.red; - fore.green = error_color.green; - fore.blue = error_color.blue; - g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); - - tag = gtk_text_buffer_create_tag (textbuf, "misc", NULL); - fore.red = misc_color.red; - fore.green = misc_color.green; - fore.blue = misc_color.blue; - g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); - - tempwid = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tempwid), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (tempwid), logwdw); - gtk_table_attach (GTK_TABLE (log_table), tempwid, 0, 1, 0, 1, - GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, - 0, 0); - logwdw_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (tempwid)); - gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0); - logwdw_textmark = gtk_text_buffer_create_mark (textbuf, "end", &iter, 1); -#endif - gtk_paned_pack2 (GTK_PANED (logpane), log_table, 1, 1); - gtk_box_pack_start (GTK_BOX (mainvbox), logpane, TRUE, TRUE, 0); - - gtk_widget_show_all (mainvbox); - return (mainvbox); +static void +chfunc (gpointer data) +{ + chdir_dialog (data); } @@ -665,66 +431,113 @@ static void -doexit (GtkWidget * widget, gpointer data) +setup_column (GtkWidget * listbox, int column, int width) { - listbox_local_width = GTK_WIDGET (local_frame)->allocation.width; - listbox_remote_width = GTK_WIDGET (remote_frame)->allocation.width; - listbox_file_height = GTK_WIDGET (remote_frame)->allocation.height; - log_height = GTK_WIDGET (log_table)->allocation.height; - transfer_height = GTK_WIDGET (transfer_scroll)->allocation.height; - - local_columns[0] = get_column (>K_CLIST (window1.listbox)->column[1]); - local_columns[1] = get_column (>K_CLIST (window1.listbox)->column[2]); - local_columns[2] = get_column (>K_CLIST (window1.listbox)->column[3]); - local_columns[3] = get_column (>K_CLIST (window1.listbox)->column[4]); - local_columns[4] = get_column (>K_CLIST (window1.listbox)->column[5]); - local_columns[5] = get_column (>K_CLIST (window1.listbox)->column[6]); - - remote_columns[0] = get_column (>K_CLIST (window2.listbox)->column[1]); - remote_columns[1] = get_column (>K_CLIST (window2.listbox)->column[2]); - remote_columns[2] = get_column (>K_CLIST (window2.listbox)->column[3]); - remote_columns[3] = get_column (>K_CLIST (window2.listbox)->column[4]); - remote_columns[4] = get_column (>K_CLIST (window2.listbox)->column[5]); - remote_columns[5] = get_column (>K_CLIST (window2.listbox)->column[6]); - - file_trans_column = get_column (>K_CLIST (dlwdw)->column[0]); - - gftp_write_config_file (); - gftp_clear_cache_files (); - exit (0); + if (width == 0) + gtk_clist_set_column_auto_resize (GTK_CLIST (listbox), column, TRUE); + else if (width == -1) + gtk_clist_set_column_visibility (GTK_CLIST (listbox), column, FALSE); + else + gtk_clist_set_column_width (GTK_CLIST (listbox), column, width); } -static int -get_column (GtkCListColumn * col) +static void +list_doaction (gftp_window_data * wdata) { - if (col->auto_resize) - return (0); - else if (!col->visible) - return (-1); - else - return (col->width); -} + GList *templist, *filelist; + int num, dir, success; + gftp_file *tempfle; + + filelist = wdata->files; + templist = GTK_CLIST (wdata->listbox)->selection; + num = 0; + templist = get_next_selection (templist, &filelist, &num); + tempfle = (gftp_file *) filelist->data; + + dir = tempfle->isdir; + success = 0; + if (tempfle->islink || tempfle->isdir) + success = chdir_dialog (wdata); -void -init_gftp (int argc, char *argv[], GtkWidget * parent) -{ - if (argc == 2 && strncmp (argv[1], "--", 2) != 0) + if (!dir && !success) { - if (gftp_parse_url (window2.request, argv[1]) == 0) - ftp_connect (&window2, window2.request, 1); - else - gftp_usage (); + switch (listbox_dblclick_action) + { + case 0: + view_dialog (wdata); + break; + case 1: + edit_dialog (wdata); + break; + case 2: + if (wdata == &window2) + get_files (wdata); + else + put_files (wdata); + break; + } } } -static void -menu_exit (GtkWidget * widget, gpointer data) +static gint +list_enter (GtkWidget * widget, GdkEventKey * event, gpointer data) +{ + gftp_window_data * wdata; + + wdata = data; + if (!GFTP_IS_CONNECTED (wdata->request)) + return (TRUE); + + if (event->type == GDK_KEY_PRESS && + (event->keyval == GDK_KP_Delete || event->keyval == GDK_Delete)) + { + delete_dialog (wdata); + return (FALSE); + } + else if (IS_ONE_SELECTED (wdata) && event->type == GDK_KEY_PRESS && + event->keyval == GDK_Return) + { + list_doaction (wdata); + return (FALSE); + } + return (TRUE); +} + + +static gint +list_dblclick (GtkWidget * widget, GdkEventButton * event, gpointer data) { - if (!delete_event (widget, NULL, data)) - doexit (widget, data); + gftp_window_data * wdata; + + wdata = data; + if (event->button == 3) + gtk_item_factory_popup (wdata->ifactory, (guint) event->x_root, + (guint) event->y_root, 3, event->time); + else if (!GFTP_IS_CONNECTED (wdata->request) || !IS_ONE_SELECTED (wdata)) + return (TRUE); + +#if GTK_MAJOR_VERSION == 1 + if (event->type == GDK_2BUTTON_PRESS && event->button == 1) + { + list_doaction (wdata); + return (FALSE); + } + return (TRUE); +#else + /* If we're using GTK 2.0, if I connect to the button_press_event signal, + whenever I get the GDK_2BUTTON_PRESS event, nothing is selected inside + the clist. But if I connect_after to the button_release_event, it seems + to only get called when we double click */ + if (event->button == 1) + { + list_doaction (wdata); + return (FALSE); + } + return (TRUE); +#endif } @@ -821,18 +634,6 @@ } -static void -setup_column (GtkWidget * listbox, int column, int width) -{ - if (width == 0) - gtk_clist_set_column_auto_resize (GTK_CLIST (listbox), column, TRUE); - else if (width == -1) - gtk_clist_set_column_visibility (GTK_CLIST (listbox), column, FALSE); - else - gtk_clist_set_column_width (GTK_CLIST (listbox), column, width); -} - - static gint menu_mouse_click (GtkWidget * widget, GdkEventButton * event, gpointer data) { @@ -846,112 +647,193 @@ } -static gint -list_dblclick (GtkWidget * widget, GdkEventButton * event, gpointer data) +static GtkWidget * +CreateFTPWindows (GtkWidget * ui) { - gftp_window_data * wdata; + GtkWidget *box, *dlbox, *winpane, *dlpane, *logpane, *mainvbox, *tempwid, + *button; + char *dltitles[2]; +#if GTK_MAJOR_VERSION > 1 + GtkTextBuffer * textbuf; + GtkTextIter iter; + GtkTextTag *tag; + GdkColor fore; +#endif + + memset (&window1, 0, sizeof (window1)); + memset (&window2, 0, sizeof (window2)); + window1.history = &localhistory; + window1.histlen = &localhistlen; + window2.history = &remotehistory; + window2.histlen = &remotehistlen; + + mainvbox = gtk_vbox_new (FALSE, 0); + + tempwid = CreateMenus (ui); + gtk_box_pack_start (GTK_BOX (mainvbox), tempwid, FALSE, FALSE, 0); - wdata = data; - if (event->button == 3) - gtk_item_factory_popup (wdata->ifactory, (guint) event->x_root, - (guint) event->y_root, 3, event->time); - else if (!GFTP_IS_CONNECTED (wdata->request) || !IS_ONE_SELECTED (wdata)) - return (TRUE); + tempwid = CreateToolbar (ui); + gtk_box_pack_start (GTK_BOX (mainvbox), tempwid, FALSE, FALSE, 0); + + winpane = gtk_hpaned_new (); + + box = gtk_hbox_new (FALSE, 0); + + local_frame = CreateFTPWindow (&window1, listbox_local_width, local_columns); + window1.sortcol = &local_sortcol; + window1.sortasds = &local_sortasds; + gtk_box_pack_start (GTK_BOX (box), local_frame, TRUE, TRUE, 0); + + dlbox = gtk_vbox_new (FALSE, 0); + gtk_container_border_width (GTK_CONTAINER (dlbox), 5); + gtk_box_pack_start (GTK_BOX (box), dlbox, FALSE, FALSE, 0); + +#if GTK_MAJOR_VERSION == 1 + tempwid = toolbar_pixmap (ui, "right.xpm"); +#else + tempwid = gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, + GTK_ICON_SIZE_SMALL_TOOLBAR); +#endif + + button = gtk_button_new (); + gtk_box_pack_start (GTK_BOX (dlbox), button, TRUE, FALSE, 0); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (put_files), NULL); + gtk_container_add (GTK_CONTAINER (button), tempwid); #if GTK_MAJOR_VERSION == 1 - if (event->type == GDK_2BUTTON_PRESS && event->button == 1) - { - list_doaction (wdata); - return (FALSE); - } - return (TRUE); + tempwid = toolbar_pixmap (ui, "left.xpm"); #else - /* If we're using GTK 2.0, if I connect to the button_press_event signal, - whenever I get the GDK_2BUTTON_PRESS event, nothing is selected inside - the clist. But if I connect_after to the button_release_event, it seems - to only get called when we double click */ - if (event->button == 1) - { - list_doaction (wdata); - return (FALSE); - } - return (TRUE); + tempwid = gtk_image_new_from_stock (GTK_STOCK_GO_BACK, + GTK_ICON_SIZE_SMALL_TOOLBAR); #endif + + button = gtk_button_new (); + gtk_box_pack_start (GTK_BOX (dlbox), button, TRUE, FALSE, 0); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (get_files), NULL); + gtk_container_add (GTK_CONTAINER (button), tempwid); + + gtk_paned_pack1 (GTK_PANED (winpane), box, 1, 1); + + remote_frame = CreateFTPWindow (&window2, listbox_remote_width, + remote_columns); + window2.sortcol = &remote_sortcol; + window2.sortasds = &remote_sortasds; + gtk_paned_pack2 (GTK_PANED (winpane), remote_frame, 1, 1); + + dlpane = gtk_vpaned_new (); + gtk_paned_pack1 (GTK_PANED (dlpane), winpane, 1, 1); + + transfer_scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_size_request (transfer_scroll, -1, transfer_height); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (transfer_scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + dltitles[0] = _("Filename"); + dltitles[1] = _("Progress"); + dlwdw = gtk_ctree_new_with_titles (2, 0, dltitles); + gtk_clist_set_selection_mode (GTK_CLIST (dlwdw), GTK_SELECTION_SINGLE); + gtk_clist_set_reorderable (GTK_CLIST (dlwdw), 0); + + if (file_trans_column == 0) + gtk_clist_set_column_auto_resize (GTK_CLIST (dlwdw), 0, TRUE); + else + gtk_clist_set_column_width (GTK_CLIST (dlwdw), 0, file_trans_column); + + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (transfer_scroll), dlwdw); + gtk_signal_connect (GTK_OBJECT (dlwdw), "button_press_event", + GTK_SIGNAL_FUNC (menu_mouse_click), (gpointer) dl_factory); + gtk_paned_pack2 (GTK_PANED (dlpane), transfer_scroll, 1, 1); + + logpane = gtk_vpaned_new (); + gtk_paned_pack1 (GTK_PANED (logpane), dlpane, 1, 1); + + log_table = gtk_table_new (1, 2, FALSE); + gtk_widget_set_size_request (log_table, -1, log_height); + +#if GTK_MAJOR_VERSION == 1 + logwdw = gtk_text_new (NULL, NULL); + + gtk_text_set_editable (GTK_TEXT (logwdw), FALSE); + gtk_text_set_word_wrap (GTK_TEXT (logwdw), TRUE); + + gtk_table_attach (GTK_TABLE (log_table), logwdw, 0, 1, 0, 1, + GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, + 0, 0); + gtk_signal_connect (GTK_OBJECT (logwdw), "button_press_event", + GTK_SIGNAL_FUNC (menu_mouse_click), + (gpointer) log_factory); + + tempwid = gtk_vscrollbar_new (GTK_TEXT (logwdw)->vadj); + gtk_table_attach (GTK_TABLE (log_table), tempwid, 1, 2, 0, 1, + GTK_FILL, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0); + logwdw_vadj = GTK_TEXT (logwdw)->vadj; +#else + logwdw = gtk_text_view_new (); + gtk_text_view_set_editable (GTK_TEXT_VIEW (logwdw), FALSE); + gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (logwdw), FALSE); + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (logwdw), GTK_WRAP_WORD); + + textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (logwdw)); + + tag = gtk_text_buffer_create_tag (textbuf, "send", NULL); + fore.red = send_color.red; + fore.green = send_color.green; + fore.blue = send_color.blue; + g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); + + tag = gtk_text_buffer_create_tag (textbuf, "recv", NULL); + fore.red = recv_color.red; + fore.green = recv_color.green; + fore.blue = recv_color.blue; + g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); + + tag = gtk_text_buffer_create_tag (textbuf, "error", NULL); + fore.red = error_color.red; + fore.green = error_color.green; + fore.blue = error_color.blue; + g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); + + tag = gtk_text_buffer_create_tag (textbuf, "misc", NULL); + fore.red = misc_color.red; + fore.green = misc_color.green; + fore.blue = misc_color.blue; + g_object_set (G_OBJECT (tag), "foreground_gdk", &fore, NULL); + + tempwid = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tempwid), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (tempwid), logwdw); + gtk_table_attach (GTK_TABLE (log_table), tempwid, 0, 1, 0, 1, + GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, + 0, 0); + logwdw_vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (tempwid)); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0); + logwdw_textmark = gtk_text_buffer_create_mark (textbuf, "end", &iter, 1); +#endif + gtk_paned_pack2 (GTK_PANED (logpane), log_table, 1, 1); + gtk_box_pack_start (GTK_BOX (mainvbox), logpane, TRUE, TRUE, 0); + + gtk_widget_show_all (mainvbox); + return (mainvbox); } -static void -list_doaction (gftp_window_data * wdata) +void +init_gftp (int argc, char *argv[], GtkWidget * parent) { - GList *templist, *filelist; - int num, dir, success; - gftp_file *tempfle; - - filelist = wdata->files; - templist = GTK_CLIST (wdata->listbox)->selection; - num = 0; - templist = get_next_selection (templist, &filelist, &num); - tempfle = (gftp_file *) filelist->data; - - dir = tempfle->isdir; - success = 0; - - if (tempfle->islink || tempfle->isdir) - success = chdir_dialog (wdata); - - if (!dir && !success) + if (argc == 2 && strncmp (argv[1], "--", 2) != 0) { - switch (listbox_dblclick_action) - { - case 0: - view_dialog (wdata); - break; - case 1: - edit_dialog (wdata); - break; - case 2: - if (wdata == &window2) - get_files (wdata); - else - put_files (wdata); - break; - } + if (gftp_parse_url (window2.request, argv[1]) == 0) + ftp_connect (&window2, window2.request, 1); + else + gftp_usage (); } } -static gint -list_enter (GtkWidget * widget, GdkEventKey * event, gpointer data) -{ - gftp_window_data * wdata; - - wdata = data; - if (!GFTP_IS_CONNECTED (wdata->request)) - return (TRUE); - - if (event->type == GDK_KEY_PRESS && - (event->keyval == GDK_KP_Delete || event->keyval == GDK_Delete)) - { - delete_dialog (wdata); - return (FALSE); - } - else if (IS_ONE_SELECTED (wdata) && event->type == GDK_KEY_PRESS && - event->keyval == GDK_Return) - { - list_doaction (wdata); - return (FALSE); - } - return (TRUE); -} - - -static void -chfunc (gpointer data) -{ - chdir_dialog (data); -} - - void toolbar_hostedit (GtkWidget * widget, gpointer data) { @@ -1095,3 +977,86 @@ pthread_kill (window2.tid, SIGINT); } + +int +main (int argc, char **argv) +{ + GtkWidget *window, *ui; + +#ifdef HAVE_GETTEXT + setlocale (LC_ALL, ""); + bindtextdomain ("gftp", LOCALE_DIR); +#if GTK_MAJOR_VERSION > 1 + bind_textdomain_codeset ("gftp", "UTF-8"); +#endif + textdomain ("gftp"); +#endif + + g_thread_init (NULL); + gtk_set_locale (); + gtk_init (&argc, &argv); + + signal (SIGCHLD, sig_child); + signal (SIGPIPE, SIG_IGN); + signal (SIGALRM, signal_handler); + signal (SIGINT, signal_handler); + + graphic_hash_table = g_hash_table_new (string_hash_function, string_hash_compare); + gftp_read_config_file (argv, 1); + if (gftp_parse_command_line (&argc, &argv) != 0) + exit (0); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_signal_connect (GTK_OBJECT (window), "delete_event", + GTK_SIGNAL_FUNC (delete_event), NULL); + gtk_signal_connect (GTK_OBJECT (window), "destroy", + GTK_SIGNAL_FUNC (destroy), NULL); + gtk_window_set_title (GTK_WINDOW (window), version); + gtk_window_set_wmclass (GTK_WINDOW(window), "main", "gFTP"); + gtk_widget_set_name (window, version); + gtk_window_set_policy (GTK_WINDOW (window), TRUE, TRUE, FALSE); + gtk_widget_realize (window); + + gftp_icon = open_xpm (window, "gftp.xpm"); + if (gftp_icon != NULL) + { + gdk_window_set_icon (window->window, NULL, gftp_icon->pixmap, + gftp_icon->bitmap); + gdk_window_set_icon_name (window->window, _("gFTP Icon")); + } + + other_wdata = &window1; + current_wdata = &window2; + ui = CreateFTPWindows (window); + gtk_container_add (GTK_CONTAINER (window), ui); + gtk_widget_show (window); + + ftp_log (gftp_logging_misc, NULL, + "%s, Copyright (C) 1998-2002 Brian Masney <", version); + ftp_log (gftp_logging_recv, NULL, "masneyb@gftp.org"); + ftp_log (gftp_logging_misc, NULL, + _(">. If you have any questions, comments, or suggestions about this program, please feel free to email them to me. You can always find out the latest news about gFTP from my website at http://www.gftp.org/\n")); + ftp_log (gftp_logging_misc, NULL, + _("gFTP comes with ABSOLUTELY NO WARRANTY; for details, see the COPYING file. This is free software, and you are welcome to redistribute it under certain conditions; for details, see the COPYING file\n")); + + gtk_timeout_add (1000, update_downloads, NULL); + gftp_protocols[GFTP_LOCAL_NUM].init (window1.request); + if (startup_directory != NULL && *startup_directory != '\0') + gftp_set_directory (window1.request, startup_directory); + gftp_connect (window1.request); + ftp_list_files (&window1, 0); + + /* On the remote window, even though we aren't connected, draw the sort + icon on that side */ + sortrows (GTK_CLIST (window2.listbox), *window2.sortcol, &window2); + + init_gftp (argc, argv, window); + gftp_is_started = 1; + + GDK_THREADS_ENTER (); + gtk_main (); + GDK_THREADS_LEAVE (); + return (0); +} + + diff -r eec25f215772 -r e5f6054590b5 src/gtk/menu-items.c --- a/src/gtk/menu-items.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/menu-items.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,10 +20,6 @@ #include static const char cvsid[] = "$Id$"; -static int do_change_dir ( gftp_window_data * wdata, - char * directory ); -static void *do_change_dir_thread ( void * data ); - void change_setting (gftp_window_data * wdata, int menuitem, GtkWidget * checkmenu) { @@ -422,6 +418,85 @@ } +static void * +do_change_dir_thread (void * data) +{ + gftp_window_data * wdata; + int success, sj; + + wdata = data; + wdata->request->user_data = (void *) 0x01; + + if (wdata->request->use_threads) + { + sj = sigsetjmp (jmp_environment, 1); + use_jmp_environment = 1; + } + else + sj = 0; + + success = 0; + if (sj == 0) + { + if (wdata->request->network_timeout > 0) + alarm (wdata->request->network_timeout); + success = gftp_set_directory (wdata->request, wdata->request->directory); + alarm (0); + } + else + { + gftp_disconnect (wdata->request); + wdata->request->logging_function (gftp_logging_error, + wdata->request->user_data, + _("Operation canceled\n")); + } + + if (wdata->request->use_threads) + use_jmp_environment = 0; + + wdata->request->user_data = NULL; + wdata->request->stopable = 0; + return ((void *) success); +} + + +static int +do_change_dir (gftp_window_data * wdata, char *directory) +{ + char *olddir; + int ret; + + if (directory != wdata->request->directory) + { + olddir = wdata->request->directory; + wdata->request->directory = g_malloc (strlen (directory) + 1); + strcpy (wdata->request->directory, directory); + } + else + olddir = NULL; + + ret = (int) generic_thread (do_change_dir_thread, wdata); + + if (!GFTP_IS_CONNECTED (wdata->request)) + { + disconnect (wdata); + if (olddir != NULL) + g_free (olddir); + return (-2); + } + + if (ret != 0) + { + g_free (wdata->request->directory); + wdata->request->directory = olddir; + } + else + g_free (olddir); + + return (ret); +} + + int chdir_edit (GtkWidget * widget, gpointer data) { @@ -505,85 +580,6 @@ } -static int -do_change_dir (gftp_window_data * wdata, char *directory) -{ - char *olddir; - int ret; - - if (directory != wdata->request->directory) - { - olddir = wdata->request->directory; - wdata->request->directory = g_malloc (strlen (directory) + 1); - strcpy (wdata->request->directory, directory); - } - else - olddir = NULL; - - ret = (int) generic_thread (do_change_dir_thread, wdata); - - if (!GFTP_IS_CONNECTED (wdata->request)) - { - disconnect (wdata); - if (olddir != NULL) - g_free (olddir); - return (-2); - } - - if (ret != 0) - { - g_free (wdata->request->directory); - wdata->request->directory = olddir; - } - else - g_free (olddir); - - return (ret); -} - - -static void * -do_change_dir_thread (void * data) -{ - gftp_window_data * wdata; - int success, sj; - - wdata = data; - wdata->request->user_data = (void *) 0x01; - - if (wdata->request->use_threads) - { - sj = sigsetjmp (jmp_environment, 1); - use_jmp_environment = 1; - } - else - sj = 0; - - success = 0; - if (sj == 0) - { - if (wdata->request->network_timeout > 0) - alarm (wdata->request->network_timeout); - success = gftp_set_directory (wdata->request, wdata->request->directory); - alarm (0); - } - else - { - gftp_disconnect (wdata->request); - wdata->request->logging_function (gftp_logging_error, - wdata->request->user_data, - _("Operation canceled\n")); - } - - if (wdata->request->use_threads) - use_jmp_environment = 0; - - wdata->request->user_data = NULL; - wdata->request->stopable = 0; - return ((void *) success); -} - - void clearlog (gpointer data) { diff -r eec25f215772 -r e5f6054590b5 src/gtk/misc-gtk.c --- a/src/gtk/misc-gtk.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/misc-gtk.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,15 +20,6 @@ #include static const char cvsid[] = "$Id$"; -static void set_menu_sensitive ( gftp_window_data * wdata, - char *path, - int sensitive ); -static gint delete_event ( GtkWidget * widget, - GdkEvent * event, - gpointer data ); -static void trans_stop_button ( GtkWidget * widget, - gpointer data ); - static GtkWidget * statuswid; @@ -298,6 +289,29 @@ } +static void +set_menu_sensitive (gftp_window_data * wdata, char *path, int sensitive) +{ + GtkWidget * tempwid; + char * pos; + + tempwid = NULL; + + if (factory != NULL) + tempwid = gtk_item_factory_get_widget (factory, path); + if (tempwid) + gtk_widget_set_sensitive (tempwid, sensitive); + + if ((pos = strchr (path + 1, '/')) == NULL) + pos = path; + + if (wdata->ifactory) + tempwid = gtk_item_factory_get_widget (wdata->ifactory, pos); + if (tempwid) + gtk_widget_set_sensitive (tempwid, sensitive); +} + + void update_window (gftp_window_data * wdata) { @@ -369,29 +383,6 @@ } -static void -set_menu_sensitive (gftp_window_data * wdata, char *path, int sensitive) -{ - GtkWidget * tempwid; - char * pos; - - tempwid = NULL; - - if (factory != NULL) - tempwid = gtk_item_factory_get_widget (factory, path); - if (tempwid) - gtk_widget_set_sensitive (tempwid, sensitive); - - if ((pos = strchr (path + 1, '/')) == NULL) - pos = path; - - if (wdata->ifactory) - tempwid = gtk_item_factory_get_widget (wdata->ifactory, pos); - if (tempwid) - gtk_widget_set_sensitive (tempwid, sensitive); -} - - GtkWidget * toolbar_pixmap (GtkWidget * widget, char *filename) { @@ -805,8 +796,8 @@ gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 1, fle->file); if (fle->attribs && (*fle->attribs == 'b' || *fle->attribs == 'c')) - tempstr = g_strdup_printf ("%d, %d", (int) fle->size >> 16, - (int) fle->size & 0xFF); + tempstr = g_strdup_printf ("%d, %d", major (fle->size), + minor (fle->size)); else tempstr = insert_commas (fle->size, NULL, 0); @@ -1107,6 +1098,23 @@ } +static gint +delete_event (GtkWidget * widget, GdkEvent * event, gpointer data) +{ + return (TRUE); +} + + +static void +trans_stop_button (GtkWidget * widget, gpointer data) +{ + gftp_transfer * transfer; + + transfer = data; + pthread_kill (((gftp_window_data *) transfer->fromwdata)->tid, SIGINT); +} + + void update_directory_download_progress (gftp_transfer * transfer) { @@ -1220,22 +1228,6 @@ } -static gint -delete_event (GtkWidget * widget, GdkEvent * event, gpointer data) -{ - return (TRUE); -} - - -static void -trans_stop_button (GtkWidget * widget, gpointer data) -{ - gftp_transfer * transfer; - - transfer = data; - pthread_kill (((gftp_window_data *) transfer->fromwdata)->tid, SIGINT); -} - void display_cached_logs (void) { diff -r eec25f215772 -r e5f6054590b5 src/gtk/options_dialog.c --- a/src/gtk/options_dialog.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/options_dialog.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,25 +20,6 @@ #include static const char cvsid[] = "$Id$"; -static void make_proxy_hosts_tab ( GtkWidget * notebook ); -static void add_host_to_listbox ( GList * templist ); -static void add_proxy_host ( GtkWidget * widget, - gpointer data ); -static void add_toggle ( GtkWidget * widget, - gpointer data ); -static void add_ok ( GtkWidget * widget, - gpointer data ); -static void delete_proxy_host ( GtkWidget * widget, - gpointer data ); -static void proxy_toggle ( GtkList * list, - GtkWidget * child, - gpointer data ); -static void apply_changes ( GtkWidget * widget, - gpointer data ); -static void clean_old_changes ( GtkWidget * widget, - gpointer data ); -static char *get_proxy_config ( void ); - static GtkWidget * proxy_text, * proxy_list, * new_proxy_domain, * network1, * network2, * network3, * network4, * netmask1, * netmask2, * netmask3, * netmask4, * domain_active, * proxy_combo, @@ -46,6 +27,178 @@ static GList * new_proxy_hosts; static char *custom_proxy; + +static void +clean_old_changes (GtkWidget * widget, gpointer data) +{ + gftp_proxy_hosts *hosts; + GList *templist; + + templist = new_proxy_hosts; + while (templist != NULL) + { + hosts = templist->data; + if (hosts->domain) + g_free (hosts->domain); + g_free (hosts); + templist = templist->next; + } + g_list_free (new_proxy_hosts); + new_proxy_hosts = NULL; + + if (custom_proxy != NULL) + { + g_free (custom_proxy); + custom_proxy = NULL; + } +} + + +static char * +get_proxy_config (void) +{ + char *newstr, *oldstr, *pos, *endpos, *textstr; + guint len; +#if GTK_MAJOR_VERSION == 1 + char tmp[128]; +#else + GtkTextBuffer * textbuf; + GtkTextIter iter, iter2; +#endif + + textstr = NULL; + newstr = g_malloc (1); + *newstr = '\0'; + +#if GTK_MAJOR_VERSION == 1 + /* + GTK_TEXT uses wchar_t instead of char in environment of multibyte encoding + locale (ex Japanese), so we must convert from wide character + to multibyte charator.... Yasuyuki Furukawa (yasu@on.cs.keio.ac.jp) + */ + if (GTK_TEXT (proxy_text)->use_wchar) + { + wcstombs (tmp, (wchar_t *) GTK_TEXT (proxy_text)->text.wc, + sizeof (tmp)); + pos = tmp; + } + else + { + oldstr = (char *) GTK_TEXT (proxy_text)->text.ch; + len = gtk_text_get_length (GTK_TEXT (proxy_text)); + textstr = g_malloc (len + 1); + strncpy (textstr, oldstr, len); + textstr[len] = '\0'; + pos = textstr; + } +#else + textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (proxy_text)); + len = gtk_text_buffer_get_char_count (textbuf); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1); + pos = textstr = gtk_text_buffer_get_text (textbuf, &iter, &iter2, 0); +#endif + + do + { + if ((endpos = strchr (pos, '\n')) != NULL) + *endpos = '\0'; + oldstr = newstr; + if (endpos != NULL) + newstr = g_strconcat (newstr, pos, "%n", NULL); + else + newstr = g_strconcat (newstr, pos, NULL); + g_free (oldstr); + if (endpos != NULL) + { + *endpos = '\n'; + pos = endpos + 1; + } + } + while (endpos != NULL); + +#if GTK_MAJOR_VERSION == 1 + if (!GTK_TEXT (proxy_text)->use_wchar) + g_free (textstr); +#else + g_free (textstr); +#endif + + return (newstr); +} + + +static void +apply_changes (GtkWidget * widget, gpointer data) +{ + const char *tempstr; + int num, found, i; + GList *templist; + + for (num = 0; config_file_vars[num].var != NULL; num++) + { + if (config_file_vars[num].widget != NULL) + { + switch (config_file_vars[num].type) + { + case CONFIG_CHECKBOX: + *(int *) config_file_vars[num].var = + GTK_TOGGLE_BUTTON (config_file_vars[num].widget)->active; + break; + case CONFIG_INTTEXT: + case CONFIG_UINTTEXT: + tempstr = gtk_entry_get_text ( + GTK_ENTRY (config_file_vars[num].widget)); + *(int *) config_file_vars[num].var = strtol (tempstr, NULL, 10); + break; + case CONFIG_FLOATTEXT: + tempstr = gtk_entry_get_text ( + GTK_ENTRY (config_file_vars[num].widget)); + *(double *) config_file_vars[num].var = strtod (tempstr, NULL); + break; + case CONFIG_CHARTEXT: + case CONFIG_CHARPASS: + tempstr = gtk_entry_get_text ( + GTK_ENTRY (config_file_vars[num].widget)); + g_free (*(char **) config_file_vars[num].var); + *(char **) config_file_vars[num].var = + g_malloc (strlen (tempstr) + 1); + strcpy (*(char **) config_file_vars[num].var, tempstr); + break; + } + } + } + + tempstr = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (def_proto_combo)->entry)); + found = 0; + for (i = 0; gftp_protocols[i].name; i++) + { + if (strcmp (gftp_protocols[i].name, tempstr) == 0) + { + found = 1; + break; + } + } + + if (found) + { + g_free (default_protocol); + default_protocol = g_strconcat (tempstr, NULL); + } + + templist = proxy_hosts; + proxy_hosts = new_proxy_hosts; + new_proxy_hosts = templist; + clean_old_changes (NULL, NULL); + + if (proxy_config != NULL) + g_free (proxy_config); + proxy_config = get_proxy_config (); + + gftp_write_config_file (); +} + + #if GTK_MAJOR_VERSION > 1 static void options_action (GtkWidget * widget, gint response, gpointer user_data) @@ -65,6 +218,502 @@ #endif +static void +proxy_toggle (GtkList * list, GtkWidget * child, gpointer data) +{ + int proxy_num; + char *str; + +#if GTK_MAJOR_VERSION > 1 + GtkTextIter iter, iter2; + GtkTextBuffer * textbuf; + guint len; +#endif + + proxy_num = gtk_list_child_position (list, child); + if (proxy_num == GFTP_CUSTOM_PROXY_NUM) + str = custom_proxy; + else + str = proxy_type[proxy_num].description; + +#if GTK_MAJOR_VERSION == 1 + gtk_text_set_point (GTK_TEXT (proxy_text), 0); + gtk_text_forward_delete (GTK_TEXT (proxy_text), + gtk_text_get_length (GTK_TEXT (proxy_text))); + + gtk_text_insert (GTK_TEXT (proxy_text), NULL, NULL, NULL, str, -1); +#else + textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (proxy_text)); + len = gtk_text_buffer_get_char_count (textbuf); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1); + gtk_text_buffer_delete (textbuf, &iter, &iter2); + + len = gtk_text_buffer_get_char_count (textbuf); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter, len - 1); + gtk_text_buffer_insert (textbuf, &iter, str, -1); +#endif +} + + +static void +add_host_to_listbox (GList * templist) +{ + gftp_proxy_hosts *hosts; + char *add_data[2]; + int num; + + hosts = templist->data; + if (hosts->domain) + { + add_data[0] = hosts->domain; + add_data[1] = NULL; + num = gtk_clist_append (GTK_CLIST (proxy_list), add_data); + } + else + { + add_data[0] = g_strdup_printf ("%d.%d.%d.%d", + hosts->ipv4_network_address >> 24 & 0xff, + hosts->ipv4_network_address >> 16 & 0xff, + hosts->ipv4_network_address >> 8 & 0xff, + hosts->ipv4_network_address & 0xff); + add_data[1] = g_strdup_printf ("%d.%d.%d.%d", + hosts->ipv4_netmask >> 24 & 0xff, + hosts->ipv4_netmask >> 16 & 0xff, + hosts->ipv4_netmask >> 8 & 0xff, + hosts->ipv4_netmask & 0xff); + num = gtk_clist_append (GTK_CLIST (proxy_list), add_data); + g_free (add_data[0]); + g_free (add_data[1]); + } + gtk_clist_set_row_data (GTK_CLIST (proxy_list), num, (gpointer) templist); +} + + +static void +add_ok (GtkWidget * widget, gpointer data) +{ + gftp_proxy_hosts *hosts; + const char *edttxt; + GList *templist; + int num; + + if ((templist = data) == NULL) + { + hosts = g_malloc0 (sizeof (*hosts)); + new_proxy_hosts = g_list_append (new_proxy_hosts, hosts); + for (templist = new_proxy_hosts; templist->next != NULL; + templist = templist->next); + } + else + { + num = gtk_clist_find_row_from_data (GTK_CLIST (proxy_list), templist); + if (num != -1) + gtk_clist_remove (GTK_CLIST (proxy_list), num); + hosts = templist->data; + } + + if (hosts->domain) + { + g_free (hosts->domain); + hosts->domain = NULL; + } + + if (GTK_TOGGLE_BUTTON (domain_active)->active) + { + edttxt = gtk_entry_get_text (GTK_ENTRY (new_proxy_domain)); + hosts->domain = g_malloc (strlen (edttxt) + 1); + strcpy (hosts->domain, edttxt); + hosts->ipv4_netmask = hosts->ipv4_network_address = 0; + } + else + { + edttxt = gtk_entry_get_text (GTK_ENTRY (network1)); + hosts->ipv4_network_address = (strtol (edttxt, NULL, 10) & 0xff) << 24; + + edttxt = gtk_entry_get_text (GTK_ENTRY (network2)); + hosts->ipv4_network_address |= (strtol (edttxt, NULL, 10) & 0xff) << 16; + + edttxt = gtk_entry_get_text (GTK_ENTRY (network3)); + hosts->ipv4_network_address |= (strtol (edttxt, NULL, 10) & 0xff) << 8; + + edttxt = gtk_entry_get_text (GTK_ENTRY (network4)); + hosts->ipv4_network_address |= strtol (edttxt, NULL, 10) & 0xff; + + edttxt = gtk_entry_get_text (GTK_ENTRY (netmask1)); + hosts->ipv4_netmask = (strtol (edttxt, NULL, 10) & 0xff) << 24; + + edttxt = gtk_entry_get_text (GTK_ENTRY (netmask2)); + hosts->ipv4_netmask |= (strtol (edttxt, NULL, 10) & 0xff) << 16; + + edttxt = gtk_entry_get_text (GTK_ENTRY (netmask3)); + hosts->ipv4_netmask |= (strtol (edttxt, NULL, 10) & 0xff) << 8; + + edttxt = gtk_entry_get_text (GTK_ENTRY (netmask4)); + hosts->ipv4_netmask |= strtol (edttxt, NULL, 10) & 0xff; + } + add_host_to_listbox (templist); +} + + +#if GTK_MAJOR_VERSION > 1 +static void +proxyhosts_action (GtkWidget * widget, gint response, gpointer user_data) +{ + switch (response) + { + case GTK_RESPONSE_OK: + add_ok (widget, user_data); + /* no break */ + default: + gtk_widget_destroy (widget); + } +} +#endif + + +static void +add_toggle (GtkWidget * widget, gpointer data) +{ + gtk_widget_set_sensitive (new_proxy_domain, data != NULL); + gtk_widget_set_sensitive (network1, data == NULL); + gtk_widget_set_sensitive (network2, data == NULL); + gtk_widget_set_sensitive (network3, data == NULL); + gtk_widget_set_sensitive (network4, data == NULL); + gtk_widget_set_sensitive (netmask1, data == NULL); + gtk_widget_set_sensitive (netmask2, data == NULL); + gtk_widget_set_sensitive (netmask3, data == NULL); + gtk_widget_set_sensitive (netmask4, data == NULL); +} + + +static void +delete_proxy_host (GtkWidget * widget, gpointer data) +{ + GList *templist; + int num; + + if ((templist = GTK_CLIST (proxy_list)->selection) == NULL) + return; + num = (int) templist->data; + templist = gtk_clist_get_row_data (GTK_CLIST (proxy_list), num); + new_proxy_hosts = g_list_remove_link (new_proxy_hosts, templist); + gtk_clist_remove (GTK_CLIST (proxy_list), num); +} + + +static void +add_proxy_host (GtkWidget * widget, gpointer data) +{ + GtkWidget *tempwid, *dialog, *frame, *box, *table; + gftp_proxy_hosts *hosts; + char *tempstr, *title; + GList *templist; + + if (data) + { + if ((templist = GTK_CLIST (proxy_list)->selection) == NULL) + return; + templist = gtk_clist_get_row_data (GTK_CLIST (proxy_list), + (int) templist->data); + hosts = templist->data; + } + else + { + hosts = NULL; + templist = NULL; + } + + title = hosts ? _("Edit Host") : _("Add Host"); +#if GTK_MAJOR_VERSION == 1 + dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog), title); + gtk_container_border_width (GTK_CONTAINER + (GTK_DIALOG (dialog)->action_area), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15); + gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE); + gtk_grab_add (dialog); +#else + dialog = gtk_dialog_new_with_buttons (title, NULL, 0, + GTK_STOCK_SAVE, + GTK_RESPONSE_OK, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + NULL); +#endif + gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 10); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); + gtk_window_set_wmclass (GTK_WINDOW(dialog), "hostinfo", "Gftp"); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); + + frame = gtk_frame_new (NULL); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, + 0); + gtk_widget_show (frame); + + box = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box), 5); + gtk_container_add (GTK_CONTAINER (frame), box); + gtk_widget_show (box); + + tempwid = gtk_label_new (_("Domain")); + gtk_box_pack_start (GTK_BOX (box), tempwid, TRUE, TRUE, 0); + gtk_widget_show (tempwid); + + new_proxy_domain = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (box), new_proxy_domain, TRUE, TRUE, 0); + gtk_widget_show (new_proxy_domain); + + frame = gtk_frame_new (NULL); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, + 0); + gtk_widget_show (frame); + + table = gtk_table_new (4, 2, FALSE); + gtk_container_border_width (GTK_CONTAINER (table), 5); + gtk_table_set_row_spacings (GTK_TABLE (table), 5); + gtk_table_set_col_spacings (GTK_TABLE (table), 5); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + tempwid = gtk_label_new (_("Network Address")); + gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 0, 1); + gtk_widget_show (tempwid); + + box = gtk_hbox_new (FALSE, 5); + gtk_table_attach_defaults (GTK_TABLE (table), box, 1, 2, 0, 1); + gtk_widget_show (box); + + network1 = gtk_entry_new (); + gtk_widget_set_size_request (network1, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), network1, TRUE, TRUE, 0); + gtk_widget_show (network1); + + network2 = gtk_entry_new (); + gtk_widget_set_size_request (network2, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), network2, TRUE, TRUE, 0); + gtk_widget_show (network2); + + network3 = gtk_entry_new (); + gtk_widget_set_size_request (network3, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), network3, TRUE, TRUE, 0); + gtk_widget_show (network3); + + network4 = gtk_entry_new (); + gtk_widget_set_size_request (network4, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), network4, TRUE, TRUE, 0); + gtk_widget_show (network4); + + tempwid = gtk_label_new (_("Netmask")); + gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 1, 2); + gtk_widget_show (tempwid); + + box = gtk_hbox_new (FALSE, 5); + gtk_table_attach_defaults (GTK_TABLE (table), box, 1, 2, 1, 2); + gtk_widget_show (box); + + netmask1 = gtk_entry_new (); + gtk_widget_set_size_request (netmask1, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), netmask1, TRUE, TRUE, 0); + gtk_widget_show (netmask1); + + netmask2 = gtk_entry_new (); + gtk_widget_set_size_request (netmask2, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), netmask2, TRUE, TRUE, 0); + gtk_widget_show (netmask2); + + netmask3 = gtk_entry_new (); + gtk_widget_set_size_request (netmask3, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), netmask3, TRUE, TRUE, 0); + gtk_widget_show (netmask3); + + netmask4 = gtk_entry_new (); + gtk_widget_set_size_request (netmask4, 28, -1); + + gtk_box_pack_start (GTK_BOX (box), netmask4, TRUE, TRUE, 0); + gtk_widget_show (netmask4); + + box = gtk_hbox_new (FALSE, 5); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, TRUE, TRUE, + 0); + gtk_widget_show (box); + + domain_active = gtk_radio_button_new_with_label (NULL, _("Domain")); + gtk_signal_connect (GTK_OBJECT (domain_active), "toggled", + GTK_SIGNAL_FUNC (add_toggle), (gpointer) 1); + gtk_box_pack_start (GTK_BOX (box), domain_active, TRUE, TRUE, 0); + gtk_widget_show (domain_active); + + tempwid = gtk_radio_button_new_with_label (gtk_radio_button_group + (GTK_RADIO_BUTTON (domain_active)), + _("Network")); + gtk_signal_connect (GTK_OBJECT (tempwid), "toggled", + GTK_SIGNAL_FUNC (add_toggle), NULL); + gtk_box_pack_start (GTK_BOX (box), tempwid, TRUE, TRUE, 0); + gtk_widget_show (tempwid); + + if (!hosts || !hosts->domain) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tempwid), TRUE); + add_toggle (NULL, NULL); + } + else + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (domain_active), TRUE); + add_toggle (NULL, (gpointer) 1); + } + + if (hosts) + { + if (hosts->domain) + gtk_entry_set_text (GTK_ENTRY (new_proxy_domain), hosts->domain); + else + { + tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address >> 24 & 0xff); + gtk_entry_set_text (GTK_ENTRY (network1), tempstr); + g_free (tempstr); + + tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address >> 16 & 0xff); + gtk_entry_set_text (GTK_ENTRY (network2), tempstr); + g_free (tempstr); + + tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address >> 8 & 0xff); + gtk_entry_set_text (GTK_ENTRY (network3), tempstr); + g_free (tempstr); + + tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address & 0xff); + gtk_entry_set_text (GTK_ENTRY (network4), tempstr); + g_free (tempstr); + + tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask >> 24 & 0xff); + gtk_entry_set_text (GTK_ENTRY (netmask1), tempstr); + g_free (tempstr); + + tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask >> 16 & 0xff); + gtk_entry_set_text (GTK_ENTRY (netmask2), tempstr); + g_free (tempstr); + + tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask >> 8 & 0xff); + gtk_entry_set_text (GTK_ENTRY (netmask3), tempstr); + g_free (tempstr); + + tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask & 0xff); + gtk_entry_set_text (GTK_ENTRY (netmask4), tempstr); + g_free (tempstr); + } + } + +#if GTK_MAJOR_VERSION == 1 + tempwid = gtk_button_new_with_label (_("OK")); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, + TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (add_ok), (gpointer) templist); + gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (dialog)); + gtk_widget_show (tempwid); + + tempwid = gtk_button_new_with_label (_(" Cancel ")); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, + TRUE, TRUE, 0); + gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (dialog)); + gtk_widget_show (tempwid); +#else + g_signal_connect (GTK_OBJECT (dialog), "response", + G_CALLBACK (proxyhosts_action), NULL); +#endif + + gtk_widget_show (dialog); +} + +static void +make_proxy_hosts_tab (GtkWidget * notebook) +{ + GtkWidget *tempwid, *box, *hbox, *scroll; + gftp_proxy_hosts *hosts, *newhosts; + char *add_data[2]; + GList *templist; + + add_data[0] = _("Network"); + add_data[1] = _("Netmask"); + + box = gtk_vbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box), 10); + gtk_widget_show (box); + + tempwid = gtk_label_new (_("Local Hosts")); + gtk_widget_show (tempwid); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), box, tempwid); + + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0); + + proxy_list = gtk_clist_new_with_titles (2, add_data); + gtk_container_add (GTK_CONTAINER (scroll), proxy_list); + gtk_clist_set_column_auto_resize (GTK_CLIST (proxy_list), 0, TRUE); + gtk_clist_set_column_auto_resize (GTK_CLIST (proxy_list), 1, TRUE); + gtk_widget_show (proxy_list); + gtk_widget_show (scroll); + + hbox = gtk_hbox_new (TRUE, 15); + gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + tempwid = gtk_button_new_with_label (_("Add")); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (add_proxy_host), NULL); + gtk_widget_show (tempwid); + + tempwid = gtk_button_new_with_label (_("Edit")); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (add_proxy_host), (gpointer) 1); + gtk_widget_show (tempwid); + + tempwid = gtk_button_new_with_label (_("Delete")); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (delete_proxy_host), NULL); + gtk_widget_show (tempwid); + + new_proxy_hosts = NULL; + for (templist = proxy_hosts; templist != NULL; + templist = templist->next) + { + hosts = templist->data; + newhosts = g_malloc (sizeof (*newhosts)); + memcpy (newhosts, hosts, sizeof (*newhosts)); + if (newhosts->domain) + { + newhosts->domain = g_malloc (strlen (hosts->domain) + 1); + strcpy (newhosts->domain, hosts->domain); + } + new_proxy_hosts = g_list_prepend (new_proxy_hosts, newhosts); + add_host_to_listbox (new_proxy_hosts); + } +} + + void options_dialog (gpointer data) { @@ -348,671 +997,3 @@ gtk_widget_show (dialog); } - -static void -make_proxy_hosts_tab (GtkWidget * notebook) -{ - GtkWidget *tempwid, *box, *hbox, *scroll; - gftp_proxy_hosts *hosts, *newhosts; - char *add_data[2]; - GList *templist; - - add_data[0] = _("Network"); - add_data[1] = _("Netmask"); - - box = gtk_vbox_new (FALSE, 5); - gtk_container_border_width (GTK_CONTAINER (box), 10); - gtk_widget_show (box); - - tempwid = gtk_label_new (_("Local Hosts")); - gtk_widget_show (tempwid); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), box, tempwid); - - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0); - - proxy_list = gtk_clist_new_with_titles (2, add_data); - gtk_container_add (GTK_CONTAINER (scroll), proxy_list); - gtk_clist_set_column_auto_resize (GTK_CLIST (proxy_list), 0, TRUE); - gtk_clist_set_column_auto_resize (GTK_CLIST (proxy_list), 1, TRUE); - gtk_widget_show (proxy_list); - gtk_widget_show (scroll); - - hbox = gtk_hbox_new (TRUE, 15); - gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - tempwid = gtk_button_new_with_label (_("Add")); - GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); - gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (add_proxy_host), NULL); - gtk_widget_show (tempwid); - - tempwid = gtk_button_new_with_label (_("Edit")); - GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); - gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (add_proxy_host), (gpointer) 1); - gtk_widget_show (tempwid); - - tempwid = gtk_button_new_with_label (_("Delete")); - GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); - gtk_box_pack_start (GTK_BOX (hbox), tempwid, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (delete_proxy_host), NULL); - gtk_widget_show (tempwid); - - new_proxy_hosts = NULL; - for (templist = proxy_hosts; templist != NULL; - templist = templist->next) - { - hosts = templist->data; - newhosts = g_malloc (sizeof (*newhosts)); - memcpy (newhosts, hosts, sizeof (*newhosts)); - if (newhosts->domain) - { - newhosts->domain = g_malloc (strlen (hosts->domain) + 1); - strcpy (newhosts->domain, hosts->domain); - } - new_proxy_hosts = g_list_prepend (new_proxy_hosts, newhosts); - add_host_to_listbox (new_proxy_hosts); - } -} - - -static void -add_host_to_listbox (GList * templist) -{ - gftp_proxy_hosts *hosts; - char *add_data[2]; - int num; - - hosts = templist->data; - if (hosts->domain) - { - add_data[0] = hosts->domain; - add_data[1] = NULL; - num = gtk_clist_append (GTK_CLIST (proxy_list), add_data); - } - else - { - add_data[0] = g_strdup_printf ("%d.%d.%d.%d", - hosts->ipv4_network_address >> 24 & 0xff, - hosts->ipv4_network_address >> 16 & 0xff, - hosts->ipv4_network_address >> 8 & 0xff, - hosts->ipv4_network_address & 0xff); - add_data[1] = g_strdup_printf ("%d.%d.%d.%d", - hosts->ipv4_netmask >> 24 & 0xff, - hosts->ipv4_netmask >> 16 & 0xff, - hosts->ipv4_netmask >> 8 & 0xff, - hosts->ipv4_netmask & 0xff); - num = gtk_clist_append (GTK_CLIST (proxy_list), add_data); - g_free (add_data[0]); - g_free (add_data[1]); - } - gtk_clist_set_row_data (GTK_CLIST (proxy_list), num, (gpointer) templist); -} - - -#if GTK_MAJOR_VERSION > 1 -static void -proxyhosts_action (GtkWidget * widget, gint response, gpointer user_data) -{ - switch (response) - { - case GTK_RESPONSE_OK: - add_ok (widget, user_data); - /* no break */ - default: - gtk_widget_destroy (widget); - } -} -#endif - - -static void -add_proxy_host (GtkWidget * widget, gpointer data) -{ - GtkWidget *tempwid, *dialog, *frame, *box, *table; - gftp_proxy_hosts *hosts; - char *tempstr, *title; - GList *templist; - - if (data) - { - if ((templist = GTK_CLIST (proxy_list)->selection) == NULL) - return; - templist = gtk_clist_get_row_data (GTK_CLIST (proxy_list), - (int) templist->data); - hosts = templist->data; - } - else - { - hosts = NULL; - templist = NULL; - } - - title = hosts ? _("Edit Host") : _("Add Host"); -#if GTK_MAJOR_VERSION == 1 - dialog = gtk_dialog_new (); - gtk_window_set_title (GTK_WINDOW (dialog), title); - gtk_container_border_width (GTK_CONTAINER - (GTK_DIALOG (dialog)->action_area), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15); - gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE); - gtk_grab_add (dialog); -#else - dialog = gtk_dialog_new_with_buttons (title, NULL, 0, - GTK_STOCK_SAVE, - GTK_RESPONSE_OK, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - NULL); -#endif - gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 10); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); - gtk_window_set_wmclass (GTK_WINDOW(dialog), "hostinfo", "Gftp"); - gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); - - frame = gtk_frame_new (NULL); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, - 0); - gtk_widget_show (frame); - - box = gtk_hbox_new (FALSE, 5); - gtk_container_border_width (GTK_CONTAINER (box), 5); - gtk_container_add (GTK_CONTAINER (frame), box); - gtk_widget_show (box); - - tempwid = gtk_label_new (_("Domain")); - gtk_box_pack_start (GTK_BOX (box), tempwid, TRUE, TRUE, 0); - gtk_widget_show (tempwid); - - new_proxy_domain = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX (box), new_proxy_domain, TRUE, TRUE, 0); - gtk_widget_show (new_proxy_domain); - - frame = gtk_frame_new (NULL); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), frame, TRUE, TRUE, - 0); - gtk_widget_show (frame); - - table = gtk_table_new (4, 2, FALSE); - gtk_container_border_width (GTK_CONTAINER (table), 5); - gtk_table_set_row_spacings (GTK_TABLE (table), 5); - gtk_table_set_col_spacings (GTK_TABLE (table), 5); - gtk_container_add (GTK_CONTAINER (frame), table); - gtk_widget_show (table); - - tempwid = gtk_label_new (_("Network Address")); - gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5); - gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 0, 1); - gtk_widget_show (tempwid); - - box = gtk_hbox_new (FALSE, 5); - gtk_table_attach_defaults (GTK_TABLE (table), box, 1, 2, 0, 1); - gtk_widget_show (box); - - network1 = gtk_entry_new (); - gtk_widget_set_size_request (network1, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), network1, TRUE, TRUE, 0); - gtk_widget_show (network1); - - network2 = gtk_entry_new (); - gtk_widget_set_size_request (network2, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), network2, TRUE, TRUE, 0); - gtk_widget_show (network2); - - network3 = gtk_entry_new (); - gtk_widget_set_size_request (network3, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), network3, TRUE, TRUE, 0); - gtk_widget_show (network3); - - network4 = gtk_entry_new (); - gtk_widget_set_size_request (network4, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), network4, TRUE, TRUE, 0); - gtk_widget_show (network4); - - tempwid = gtk_label_new (_("Netmask")); - gtk_misc_set_alignment (GTK_MISC (tempwid), 1, 0.5); - gtk_table_attach_defaults (GTK_TABLE (table), tempwid, 0, 1, 1, 2); - gtk_widget_show (tempwid); - - box = gtk_hbox_new (FALSE, 5); - gtk_table_attach_defaults (GTK_TABLE (table), box, 1, 2, 1, 2); - gtk_widget_show (box); - - netmask1 = gtk_entry_new (); - gtk_widget_set_size_request (netmask1, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), netmask1, TRUE, TRUE, 0); - gtk_widget_show (netmask1); - - netmask2 = gtk_entry_new (); - gtk_widget_set_size_request (netmask2, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), netmask2, TRUE, TRUE, 0); - gtk_widget_show (netmask2); - - netmask3 = gtk_entry_new (); - gtk_widget_set_size_request (netmask3, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), netmask3, TRUE, TRUE, 0); - gtk_widget_show (netmask3); - - netmask4 = gtk_entry_new (); - gtk_widget_set_size_request (netmask4, 28, -1); - - gtk_box_pack_start (GTK_BOX (box), netmask4, TRUE, TRUE, 0); - gtk_widget_show (netmask4); - - box = gtk_hbox_new (FALSE, 5); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, TRUE, TRUE, - 0); - gtk_widget_show (box); - - domain_active = gtk_radio_button_new_with_label (NULL, _("Domain")); - gtk_signal_connect (GTK_OBJECT (domain_active), "toggled", - GTK_SIGNAL_FUNC (add_toggle), (gpointer) 1); - gtk_box_pack_start (GTK_BOX (box), domain_active, TRUE, TRUE, 0); - gtk_widget_show (domain_active); - - tempwid = gtk_radio_button_new_with_label (gtk_radio_button_group - (GTK_RADIO_BUTTON (domain_active)), - _("Network")); - gtk_signal_connect (GTK_OBJECT (tempwid), "toggled", - GTK_SIGNAL_FUNC (add_toggle), NULL); - gtk_box_pack_start (GTK_BOX (box), tempwid, TRUE, TRUE, 0); - gtk_widget_show (tempwid); - - if (!hosts || !hosts->domain) - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tempwid), TRUE); - add_toggle (NULL, NULL); - } - else - { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (domain_active), TRUE); - add_toggle (NULL, (gpointer) 1); - } - - if (hosts) - { - if (hosts->domain) - gtk_entry_set_text (GTK_ENTRY (new_proxy_domain), hosts->domain); - else - { - tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address >> 24 & 0xff); - gtk_entry_set_text (GTK_ENTRY (network1), tempstr); - g_free (tempstr); - - tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address >> 16 & 0xff); - gtk_entry_set_text (GTK_ENTRY (network2), tempstr); - g_free (tempstr); - - tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address >> 8 & 0xff); - gtk_entry_set_text (GTK_ENTRY (network3), tempstr); - g_free (tempstr); - - tempstr = g_strdup_printf ("%d", hosts->ipv4_network_address & 0xff); - gtk_entry_set_text (GTK_ENTRY (network4), tempstr); - g_free (tempstr); - - tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask >> 24 & 0xff); - gtk_entry_set_text (GTK_ENTRY (netmask1), tempstr); - g_free (tempstr); - - tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask >> 16 & 0xff); - gtk_entry_set_text (GTK_ENTRY (netmask2), tempstr); - g_free (tempstr); - - tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask >> 8 & 0xff); - gtk_entry_set_text (GTK_ENTRY (netmask3), tempstr); - g_free (tempstr); - - tempstr = g_strdup_printf ("%d", hosts->ipv4_netmask & 0xff); - gtk_entry_set_text (GTK_ENTRY (netmask4), tempstr); - g_free (tempstr); - } - } - -#if GTK_MAJOR_VERSION == 1 - tempwid = gtk_button_new_with_label (_("OK")); - GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, - TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (add_ok), (gpointer) templist); - gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (gtk_widget_destroy), - GTK_OBJECT (dialog)); - gtk_widget_show (tempwid); - - tempwid = gtk_button_new_with_label (_(" Cancel ")); - GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, - TRUE, TRUE, 0); - gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", - GTK_SIGNAL_FUNC (gtk_widget_destroy), - GTK_OBJECT (dialog)); - gtk_widget_show (tempwid); -#else - g_signal_connect (GTK_OBJECT (dialog), "response", - G_CALLBACK (proxyhosts_action), NULL); -#endif - - gtk_widget_show (dialog); -} - - -static void -add_toggle (GtkWidget * widget, gpointer data) -{ - gtk_widget_set_sensitive (new_proxy_domain, data != NULL); - gtk_widget_set_sensitive (network1, data == NULL); - gtk_widget_set_sensitive (network2, data == NULL); - gtk_widget_set_sensitive (network3, data == NULL); - gtk_widget_set_sensitive (network4, data == NULL); - gtk_widget_set_sensitive (netmask1, data == NULL); - gtk_widget_set_sensitive (netmask2, data == NULL); - gtk_widget_set_sensitive (netmask3, data == NULL); - gtk_widget_set_sensitive (netmask4, data == NULL); -} - - -static void -add_ok (GtkWidget * widget, gpointer data) -{ - gftp_proxy_hosts *hosts; - const char *edttxt; - GList *templist; - int num; - - if ((templist = data) == NULL) - { - hosts = g_malloc0 (sizeof (*hosts)); - new_proxy_hosts = g_list_append (new_proxy_hosts, hosts); - for (templist = new_proxy_hosts; templist->next != NULL; - templist = templist->next); - } - else - { - num = gtk_clist_find_row_from_data (GTK_CLIST (proxy_list), templist); - if (num != -1) - gtk_clist_remove (GTK_CLIST (proxy_list), num); - hosts = templist->data; - } - - if (hosts->domain) - { - g_free (hosts->domain); - hosts->domain = NULL; - } - - if (GTK_TOGGLE_BUTTON (domain_active)->active) - { - edttxt = gtk_entry_get_text (GTK_ENTRY (new_proxy_domain)); - hosts->domain = g_malloc (strlen (edttxt) + 1); - strcpy (hosts->domain, edttxt); - hosts->ipv4_netmask = hosts->ipv4_network_address = 0; - } - else - { - edttxt = gtk_entry_get_text (GTK_ENTRY (network1)); - hosts->ipv4_network_address = (strtol (edttxt, NULL, 10) & 0xff) << 24; - - edttxt = gtk_entry_get_text (GTK_ENTRY (network2)); - hosts->ipv4_network_address |= (strtol (edttxt, NULL, 10) & 0xff) << 16; - - edttxt = gtk_entry_get_text (GTK_ENTRY (network3)); - hosts->ipv4_network_address |= (strtol (edttxt, NULL, 10) & 0xff) << 8; - - edttxt = gtk_entry_get_text (GTK_ENTRY (network4)); - hosts->ipv4_network_address |= strtol (edttxt, NULL, 10) & 0xff; - - edttxt = gtk_entry_get_text (GTK_ENTRY (netmask1)); - hosts->ipv4_netmask = (strtol (edttxt, NULL, 10) & 0xff) << 24; - - edttxt = gtk_entry_get_text (GTK_ENTRY (netmask2)); - hosts->ipv4_netmask |= (strtol (edttxt, NULL, 10) & 0xff) << 16; - - edttxt = gtk_entry_get_text (GTK_ENTRY (netmask3)); - hosts->ipv4_netmask |= (strtol (edttxt, NULL, 10) & 0xff) << 8; - - edttxt = gtk_entry_get_text (GTK_ENTRY (netmask4)); - hosts->ipv4_netmask |= strtol (edttxt, NULL, 10) & 0xff; - } - add_host_to_listbox (templist); -} - - -static void -delete_proxy_host (GtkWidget * widget, gpointer data) -{ - GList *templist; - int num; - - if ((templist = GTK_CLIST (proxy_list)->selection) == NULL) - return; - num = (int) templist->data; - templist = gtk_clist_get_row_data (GTK_CLIST (proxy_list), num); - new_proxy_hosts = g_list_remove_link (new_proxy_hosts, templist); - gtk_clist_remove (GTK_CLIST (proxy_list), num); -} - - -static void -proxy_toggle (GtkList * list, GtkWidget * child, gpointer data) -{ - int proxy_num; - char *str; - -#if GTK_MAJOR_VERSION > 1 - GtkTextIter iter, iter2; - GtkTextBuffer * textbuf; - guint len; -#endif - - proxy_num = gtk_list_child_position (list, child); - if (proxy_num == GFTP_CUSTOM_PROXY_NUM) - str = custom_proxy; - else - str = proxy_type[proxy_num].description; - -#if GTK_MAJOR_VERSION == 1 - gtk_text_set_point (GTK_TEXT (proxy_text), 0); - gtk_text_forward_delete (GTK_TEXT (proxy_text), - gtk_text_get_length (GTK_TEXT (proxy_text))); - - gtk_text_insert (GTK_TEXT (proxy_text), NULL, NULL, NULL, str, -1); -#else - textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (proxy_text)); - len = gtk_text_buffer_get_char_count (textbuf); - gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0); - gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1); - gtk_text_buffer_delete (textbuf, &iter, &iter2); - - len = gtk_text_buffer_get_char_count (textbuf); - gtk_text_buffer_get_iter_at_offset (textbuf, &iter, len - 1); - gtk_text_buffer_insert (textbuf, &iter, str, -1); -#endif -} - - -static void -apply_changes (GtkWidget * widget, gpointer data) -{ - const char *tempstr; - int num, found, i; - GList *templist; - - for (num = 0; config_file_vars[num].var != NULL; num++) - { - if (config_file_vars[num].widget != NULL) - { - switch (config_file_vars[num].type) - { - case CONFIG_CHECKBOX: - *(int *) config_file_vars[num].var = - GTK_TOGGLE_BUTTON (config_file_vars[num].widget)->active; - break; - case CONFIG_INTTEXT: - case CONFIG_UINTTEXT: - tempstr = gtk_entry_get_text ( - GTK_ENTRY (config_file_vars[num].widget)); - *(int *) config_file_vars[num].var = strtol (tempstr, NULL, 10); - break; - case CONFIG_FLOATTEXT: - tempstr = gtk_entry_get_text ( - GTK_ENTRY (config_file_vars[num].widget)); - *(double *) config_file_vars[num].var = strtod (tempstr, NULL); - break; - case CONFIG_CHARTEXT: - case CONFIG_CHARPASS: - tempstr = gtk_entry_get_text ( - GTK_ENTRY (config_file_vars[num].widget)); - g_free (*(char **) config_file_vars[num].var); - *(char **) config_file_vars[num].var = - g_malloc (strlen (tempstr) + 1); - strcpy (*(char **) config_file_vars[num].var, tempstr); - break; - } - } - } - - tempstr = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (def_proto_combo)->entry)); - found = 0; - for (i = 0; gftp_protocols[i].name; i++) - { - if (strcmp (gftp_protocols[i].name, tempstr) == 0) - { - found = 1; - break; - } - } - - if (found) - { - g_free (default_protocol); - default_protocol = g_strconcat (tempstr, NULL); - } - - templist = proxy_hosts; - proxy_hosts = new_proxy_hosts; - new_proxy_hosts = templist; - clean_old_changes (NULL, NULL); - - if (proxy_config != NULL) - g_free (proxy_config); - proxy_config = get_proxy_config (); - - gftp_write_config_file (); -} - - -static void -clean_old_changes (GtkWidget * widget, gpointer data) -{ - gftp_proxy_hosts *hosts; - GList *templist; - - templist = new_proxy_hosts; - while (templist != NULL) - { - hosts = templist->data; - if (hosts->domain) - g_free (hosts->domain); - g_free (hosts); - templist = templist->next; - } - g_list_free (new_proxy_hosts); - new_proxy_hosts = NULL; - - if (custom_proxy != NULL) - { - g_free (custom_proxy); - custom_proxy = NULL; - } -} - - -static char * -get_proxy_config (void) -{ - char *newstr, *oldstr, *pos, *endpos, *textstr; - guint len; -#if GTK_MAJOR_VERSION == 1 - char tmp[128]; -#else - GtkTextBuffer * textbuf; - GtkTextIter iter, iter2; -#endif - - textstr = NULL; - newstr = g_malloc (1); - *newstr = '\0'; - -#if GTK_MAJOR_VERSION == 1 - /* - GTK_TEXT uses wchar_t instead of char in environment of multibyte encoding - locale (ex Japanese), so we must convert from wide character - to multibyte charator.... Yasuyuki Furukawa (yasu@on.cs.keio.ac.jp) - */ - if (GTK_TEXT (proxy_text)->use_wchar) - { - wcstombs (tmp, (wchar_t *) GTK_TEXT (proxy_text)->text.wc, - sizeof (tmp)); - pos = tmp; - } - else - { - oldstr = (char *) GTK_TEXT (proxy_text)->text.ch; - len = gtk_text_get_length (GTK_TEXT (proxy_text)); - textstr = g_malloc (len + 1); - strncpy (textstr, oldstr, len); - textstr[len] = '\0'; - pos = textstr; - } -#else - textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (proxy_text)); - len = gtk_text_buffer_get_char_count (textbuf); - gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0); - gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, len - 1); - pos = textstr = gtk_text_buffer_get_text (textbuf, &iter, &iter2, 0); -#endif - - do - { - if ((endpos = strchr (pos, '\n')) != NULL) - *endpos = '\0'; - oldstr = newstr; - if (endpos != NULL) - newstr = g_strconcat (newstr, pos, "%n", NULL); - else - newstr = g_strconcat (newstr, pos, NULL); - g_free (oldstr); - if (endpos != NULL) - { - *endpos = '\n'; - pos = endpos + 1; - } - } - while (endpos != NULL); - -#if GTK_MAJOR_VERSION == 1 - if (!GTK_TEXT (proxy_text)->use_wchar) - g_free (textstr); -#else - g_free (textstr); -#endif - - return (newstr); -} - diff -r eec25f215772 -r e5f6054590b5 src/gtk/transfer.c --- a/src/gtk/transfer.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/transfer.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,104 +20,53 @@ #include static const char cvsid[] = "$Id$"; -static void *getdir_thread ( void *data ); -static void *connect_thread ( void *data ); -static void on_next_transfer ( gftp_transfer * tdata ); -static void show_transfer ( gftp_transfer * tdata ); -static void transfer_done ( GList * node ); -static void create_transfer ( gftp_transfer * tdata ); -static void update_file_status ( gftp_transfer * tdata ); -static void trans_selectall ( GtkWidget * widget, - gpointer data ); -static void trans_unselectall ( GtkWidget * widget, - gpointer data ); -static void overwrite ( GtkWidget * widget, - gpointer data ); -static void resume ( GtkWidget * widget, - gpointer data ); -static void skip ( GtkWidget * widget, - gpointer data ); -static void ok ( GtkWidget * widget, - gpointer data ); -static void cancel ( GtkWidget * widget, - gpointer data ); -static void gftp_gtk_calc_kbs ( gftp_transfer * tdata, - ssize_t num_read ); -static void check_done_process ( void ); -static void do_upload ( gftp_viewedit_data * ve_proc, - gftp_dialog_data * ddata ); -static void dont_upload ( gftp_viewedit_data * ve_proc, - gftp_dialog_data * ddata ); -static void free_edit_data ( gftp_viewedit_data *ve_proc ); -static int get_status ( gftp_transfer * tdata, - ssize_t num_read ); -static void wakeup_main_thread ( gpointer data, - gint source, - GdkInputCondition condition ); -static gint setup_wakeup_main_thread ( gftp_request * request ); -static void teardown_wakeup_main_thread ( gftp_request * request, - gint handler ); -static mode_t parse_attribs ( char *attribs ); -static void remove_file ( char *filename ); - static GtkWidget * dialog; -int -ftp_list_files (gftp_window_data * wdata, int usecache) +static void +wakeup_main_thread (gpointer data, gint source, GdkInputCondition condition) { - guint handler; - void *success; - - gtk_label_set (GTK_LABEL (wdata->hoststxt), _("Receiving file names...")); - if (gftp_is_started) - fix_display (); + gftp_request * request; + char c; + + request = data; + if (request->wakeup_main_thread[0] > 0) + read (request->wakeup_main_thread[0], &c, 1); +} - wdata->show_selected = 0; - if (wdata->files == NULL) - { - if (check_reconnect (wdata) < 0) - return (0); - gtk_clist_freeze (GTK_CLIST (wdata->listbox)); - wdata->request->stopable = 1; - if (wdata->request->use_threads) - { - gtk_widget_set_sensitive (stop_btn, 1); +static gint +setup_wakeup_main_thread (gftp_request * request) +{ + gint handler; - handler = setup_wakeup_main_thread (wdata->request); - pthread_create (&wdata->tid, NULL, getdir_thread, wdata->request); - while (wdata->request->stopable) - { - GDK_THREADS_LEAVE (); -#if GTK_MAJOR_VERSION == 1 - g_main_iteration (TRUE); -#else - g_main_context_iteration (NULL, TRUE); -#endif - } - teardown_wakeup_main_thread (wdata->request, handler); + if (socketpair (AF_UNIX, SOCK_STREAM, 0, request->wakeup_main_thread) == 0) + { + /* FIXME - depreciated in GDK 2.0 */ + handler = gdk_input_add (request->wakeup_main_thread[0], + GDK_INPUT_READ, wakeup_main_thread, request); + } + else + { + request->wakeup_main_thread[0] = 0; + request->wakeup_main_thread[1] = 0; + handler = 0; + } + return (handler); +} - pthread_join (wdata->tid, &success); - gtk_widget_set_sensitive (stop_btn, 0); - } - else - success = getdir_thread (wdata->request); - wdata->files = success; - gtk_clist_thaw (GTK_CLIST (wdata->listbox)); - memset (&wdata->tid, 0, sizeof (wdata->tid)); + +static void +teardown_wakeup_main_thread (gftp_request * request, gint handler) +{ + if (request->wakeup_main_thread[0] > 0 && request->wakeup_main_thread[1] > 0) + { + /* FIXME - depreciated in GDK 2.0 */ + gdk_input_remove (handler); + close (request->wakeup_main_thread[0]); + close (request->wakeup_main_thread[1]); + request->wakeup_main_thread[0] = 0; + request->wakeup_main_thread[1] = 0; } - - if (wdata->files == NULL || !GFTP_IS_CONNECTED (wdata->request)) - { - disconnect (wdata); - return (0); - } - - wdata->sorted = 0; - sortrows (GTK_CLIST (wdata->listbox), *wdata->sortcol, (gpointer) wdata); - if (IS_NONE_SELECTED (wdata)) - gtk_clist_select_row (GTK_CLIST (wdata->listbox), 0, 0); - return (1); } @@ -214,6 +163,65 @@ } +int +ftp_list_files (gftp_window_data * wdata, int usecache) +{ + guint handler; + void *success; + + gtk_label_set (GTK_LABEL (wdata->hoststxt), _("Receiving file names...")); + if (gftp_is_started) + fix_display (); + + wdata->show_selected = 0; + if (wdata->files == NULL) + { + if (check_reconnect (wdata) < 0) + return (0); + + gtk_clist_freeze (GTK_CLIST (wdata->listbox)); + wdata->request->stopable = 1; + if (wdata->request->use_threads) + { + gtk_widget_set_sensitive (stop_btn, 1); + + handler = setup_wakeup_main_thread (wdata->request); + pthread_create (&wdata->tid, NULL, getdir_thread, wdata->request); + while (wdata->request->stopable) + { + GDK_THREADS_LEAVE (); +#if GTK_MAJOR_VERSION == 1 + g_main_iteration (TRUE); +#else + g_main_context_iteration (NULL, TRUE); +#endif + } + teardown_wakeup_main_thread (wdata->request, handler); + + pthread_join (wdata->tid, &success); + gtk_widget_set_sensitive (stop_btn, 0); + } + else + success = getdir_thread (wdata->request); + wdata->files = success; + gtk_clist_thaw (GTK_CLIST (wdata->listbox)); + memset (&wdata->tid, 0, sizeof (wdata->tid)); + } + + if (wdata->files == NULL || !GFTP_IS_CONNECTED (wdata->request)) + { + disconnect (wdata); + return (0); + } + + wdata->sorted = 0; + sortrows (GTK_CLIST (wdata->listbox), *wdata->sortcol, (gpointer) wdata); + if (IS_NONE_SELECTED (wdata)) + gtk_clist_select_row (GTK_CLIST (wdata->listbox), 0, 0); + return (1); +} + + static void try_connect_again (gftp_request * request, gftp_dialog_data * ddata) { @@ -229,6 +237,63 @@ } +static void * +connect_thread (void *data) +{ + static int conn_num; + gftp_request * request; + int ret, sj; + + request = data; + request->user_data = (void *) 0x1; + + conn_num = 0; + if (request->use_threads) + { + sj = sigsetjmp (jmp_environment, 1); + use_jmp_environment = 1; + } + else + sj = 0; + + ret = 0; + if (sj != 0) + { + ret = 0; + gftp_disconnect (request); + } + + while (sj != 1 && (request->retries == 0 || conn_num < request->retries)) + { + conn_num++; + if (request->network_timeout > 0) + alarm (request->network_timeout); + ret = gftp_connect (request) == 0; + alarm (0); + + if (ret) + break; + else if (request->retries == 0 || conn_num < request->retries) + { + request->logging_function (gftp_logging_misc, request->user_data, + _("Waiting %d seconds until trying to connect again\n"), + request->sleep_time); + alarm (request->sleep_time); + pause (); + } + } + + if (request->use_threads) + use_jmp_environment = 0; + + request->user_data = NULL; + request->stopable = 0; + if (request->wakeup_main_thread[1] > 0) + write (request->wakeup_main_thread[1], " ", 1); + return ((void *) ret); +} + + int ftp_connect (gftp_window_data * wdata, gftp_request * request, int getdir) { @@ -316,63 +381,6 @@ } -static void * -connect_thread (void *data) -{ - static int conn_num; - gftp_request * request; - int ret, sj; - - request = data; - request->user_data = (void *) 0x1; - - conn_num = 0; - if (request->use_threads) - { - sj = sigsetjmp (jmp_environment, 1); - use_jmp_environment = 1; - } - else - sj = 0; - - ret = 0; - if (sj != 0) - { - ret = 0; - gftp_disconnect (request); - } - - while (sj != 1 && (request->retries == 0 || conn_num < request->retries)) - { - conn_num++; - if (request->network_timeout > 0) - alarm (request->network_timeout); - ret = gftp_connect (request) == 0; - alarm (0); - - if (ret) - break; - else if (request->retries == 0 || conn_num < request->retries) - { - request->logging_function (gftp_logging_misc, request->user_data, - _("Waiting %d seconds until trying to connect again\n"), - request->sleep_time); - alarm (request->sleep_time); - pause (); - } - } - - if (request->use_threads) - use_jmp_environment = 0; - - request->user_data = NULL; - request->stopable = 0; - if (request->wakeup_main_thread[1] > 0) - write (request->wakeup_main_thread[1], " ", 1); - return ((void *) ret); -} - - void get_files (gpointer data) { @@ -544,6 +552,193 @@ } +static void +gftp_gtk_calc_kbs (gftp_transfer * tdata, ssize_t num_read) +{ + unsigned long waitusecs; + double difftime, curkbs; + gftp_file * tempfle; + struct timeval tv; + unsigned long toadd; + + gettimeofday (&tv, NULL); + pthread_mutex_lock (tdata->statmutex); + + tempfle = tdata->curfle->data; + tdata->trans_bytes += num_read; + tdata->curtrans += num_read; + tdata->stalled = 0; + + difftime = (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0); + if (difftime <= 0) + tdata->kbs = (double) tdata->trans_bytes / 1024.0; + else + tdata->kbs = (double) tdata->trans_bytes / 1024.0 / difftime; + + difftime = (tv.tv_sec - tdata->lasttime.tv_sec) + ((double) (tv.tv_usec - tdata->lasttime.tv_usec) / 1000000.0); + + if (difftime <= 0) + curkbs = (double) (num_read / 1024.0); + else + curkbs = (double) (num_read / 1024.0 / difftime); + + if (tdata->fromreq->maxkbs > 0 && + curkbs > tdata->fromreq->maxkbs) + { + waitusecs = (double) num_read / 1024.0 / tdata->fromreq->maxkbs * 1000000.0 - difftime; + + if (waitusecs > 0) + { + pthread_mutex_unlock (tdata->statmutex); + difftime += ((double) waitusecs / 1000000.0); + usleep (waitusecs); + pthread_mutex_lock (tdata->statmutex); + } + } + + /* I don't call gettimeofday (&tdata->lasttime) here because this will use + less system resources. This will be close enough for what we need */ + difftime += tdata->lasttime.tv_usec / 1000000.0; + toadd = (long) difftime; + difftime -= toadd; + tdata->lasttime.tv_sec += toadd; + tdata->lasttime.tv_usec = difftime * 1000000.0; + + pthread_mutex_unlock (tdata->statmutex); +} + + +static int +get_status (gftp_transfer * tdata, ssize_t num_read) +{ + gftp_file * tempfle; + struct timeval tv; + + pthread_mutex_lock (tdata->structmutex); + if (tdata->curfle == NULL) + { + pthread_mutex_unlock (tdata->structmutex); + return (-1); + } + tempfle = tdata->curfle->data; + pthread_mutex_unlock (tdata->structmutex); + + gftp_disconnect (tdata->fromreq); + gftp_disconnect (tdata->toreq); + if (num_read < 0 || tdata->skip_file) + { + if (tdata->fromreq->retries != 0 && tdata->current_file_retries >= tdata->fromreq->retries) + { + tdata->fromreq->logging_function (gftp_logging_error, + tdata->fromreq->user_data, + _("Error: Remote site %s disconnected. Max retries reached...giving up\n"), + tdata->fromreq->hostname != NULL ? + tdata->fromreq->hostname : tdata->toreq->hostname); + return (-1); + } + else + { + tdata->fromreq->logging_function (gftp_logging_error, + tdata->fromreq->user_data, + _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"), + tdata->fromreq->hostname != NULL ? + tdata->fromreq->hostname : tdata->toreq->hostname, + tdata->fromreq->sleep_time); + } + + while (tdata->fromreq->retries == 0 || + tdata->current_file_retries <= tdata->fromreq->retries) + { + if (!tdata->skip_file) + { + tv.tv_sec = tdata->fromreq->sleep_time; + tv.tv_usec = 0; + select (0, NULL, NULL, NULL, &tv); + } + + if (gftp_connect (tdata->fromreq) == 0 && + gftp_connect (tdata->toreq) == 0) + { + pthread_mutex_lock (tdata->structmutex); + tdata->resumed_bytes = tdata->resumed_bytes + tdata->trans_bytes - tdata->curresumed - tdata->curtrans; + tdata->trans_bytes = 0; + if (tdata->skip_file) + { + tdata->total_bytes -= tempfle->size; + tdata->curtrans = 0; + + tdata->curfle = tdata->curfle->next; + tdata->next_file = 1; + tdata->skip_file = 0; + tdata->cancel = 0; + tdata->fromreq->cancel = 0; + tdata->toreq->cancel = 0; + } + else + { + tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; + tempfle->startsize = tdata->curtrans + tdata->curresumed; + /* We decrement this here because it will be incremented in + the loop again */ + tdata->curresumed = 0; + tdata->current_file_number--; /* Decrement this because it + will be incremented when we + continue in the loop */ + } + gettimeofday (&tdata->starttime, NULL); + pthread_mutex_unlock (tdata->structmutex); + return (1); + } + else + tdata->current_file_retries++; + } + } + else if (tdata->cancel) + return (-1); + + return (0); +} + + +static mode_t +parse_attribs (char *attribs) +{ + mode_t mode; + int cur; + + cur = 0; + if (attribs[1] == 'r') + cur += 4; + if (attribs[2] == 'w') + cur += 2; + if (attribs[3] == 'x' || + attribs[3] == 's') + cur += 1; + mode = cur; + + cur = 0; + if (attribs[4] == 'r') + cur += 4; + if (attribs[5] == 'w') + cur += 2; + if (attribs[6] == 'x' || + attribs[6] == 's') + cur += 1; + mode = (mode * 10) + cur; + + cur = 0; + if (attribs[7] == 'r') + cur += 4; + if (attribs[8] == 'w') + cur += 2; + if (attribs[9] == 'x' || + attribs[9] == 's') + cur += 1; + mode = (mode * 10) + cur; + + return (mode); +} + void * gftp_gtk_transfer_files (void *data) @@ -925,70 +1120,126 @@ } -gint -update_downloads (gpointer data) +static void +remove_file (char *filename) +{ + if (unlink (filename) == 0) + ftp_log (gftp_logging_misc, NULL, _("Successfully removed %s\n"), + filename); + else + ftp_log (gftp_logging_error, NULL, + _("Error: Could not remove file %s: %s\n"), filename, + g_strerror (errno)); +} + + +static void +free_edit_data (gftp_viewedit_data * ve_proc) +{ + int i; + + if (ve_proc->filename) + g_free (ve_proc->filename); + if (ve_proc->remote_filename) + g_free (ve_proc->remote_filename); + for (i = 0; ve_proc->argv[i] != NULL; i++) + g_free (ve_proc->argv[i]); + g_free (ve_proc->argv); + g_free (ve_proc); +} + + +static void +dont_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) { - char tempstr[50], temp1str[127]; - GList * templist, * next; - gftp_transfer * tdata; + remove_file (ve_proc->filename); + free_edit_data (ve_proc); +} + + +static void +do_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) +{ + gftp_file * tempfle; + GList * newfile; - if (file_transfer_logs != NULL) - display_cached_logs (); + tempfle = g_malloc0 (sizeof (*tempfle)); + tempfle->destfile = ve_proc->remote_filename; + ve_proc->remote_filename = NULL; + tempfle->file = ve_proc->filename; + ve_proc->filename = NULL; + tempfle->done_rm = 1; + newfile = g_list_append (NULL, tempfle); + add_file_transfer (ve_proc->fromwdata->request, ve_proc->towdata->request, + ve_proc->fromwdata, ve_proc->towdata, newfile, 1); + free_edit_data (ve_proc); +} + - if (window2.request->gotbytes != 0) +static void +check_done_process (void) +{ + gftp_viewedit_data * ve_proc; + GList * curdata, *deldata; + struct stat st; + int ret; + char *str; + pid_t pid; + + viewedit_process_done = 0; + while ((pid = waitpid (-1, &ret, WNOHANG)) > 0) { - if (window2.request->gotbytes == -1) - { - update_window_info (); - window2.request->gotbytes = 0; - } - else - { - insert_commas (window2.request->gotbytes, tempstr, sizeof (tempstr)); - g_snprintf (temp1str, sizeof (temp1str), - _("Retrieving file names...%s bytes"), tempstr); - gtk_label_set (GTK_LABEL (window2.hoststxt), temp1str); + curdata = viewedit_processes; + while (curdata != NULL) + { + ve_proc = curdata->data; + deldata = curdata; + curdata = curdata->next; + if (ve_proc->pid == pid) + { + viewedit_processes = g_list_remove_link (viewedit_processes, + deldata); + if (ret != 0) + ftp_log (gftp_logging_error, NULL, + _("Error: Child %d returned %d\n"), pid, ret); + else + ftp_log (gftp_logging_misc, NULL, + _("Child %d returned successfully\n"), pid); + + if (!ve_proc->view && !ve_proc->dontupload) + { + /* We was editing the file. Upload it */ + if (stat (ve_proc->filename, &st) == -1) + ftp_log (gftp_logging_error, NULL, + _("Error: Cannot get information about file %s: %s\n"), + ve_proc->filename, g_strerror (errno)); + else if (st.st_mtime == ve_proc->st.st_mtime) + { + ftp_log (gftp_logging_misc, NULL, + _("File %s was not changed\n"), + ve_proc->filename); + remove_file (ve_proc->filename); + } + else + { + memcpy (&ve_proc->st, &st, sizeof (ve_proc->st)); + str = g_strdup_printf ( + _("File %s has changed.\nWould you like to upload it?"), + ve_proc->remote_filename); + + MakeYesNoDialog (_("Edit File"), str, + do_upload, ve_proc, + dont_upload, ve_proc); + g_free (str); + continue; + } + } + + free_edit_data (ve_proc); + continue; + } } } - - if (viewedit_process_done) - check_done_process (); - - for (templist = file_transfers; templist != NULL;) - { - tdata = templist->data; - if (tdata->ready) - { - pthread_mutex_lock (tdata->structmutex); - - if (tdata->next_file) - on_next_transfer (tdata); - else if (tdata->show) - show_transfer (tdata); - else if (tdata->done) - { - next = templist->next; - transfer_done (templist); - templist = next; - continue; - } - - if (tdata->curfle != NULL) - { - if (!tdata->started && start_file_transfers && - (transfer_in_progress == 0 || !do_one_transfer_at_a_time)) - create_transfer (tdata); - - if (tdata->started) - update_file_status (tdata); - } - pthread_mutex_unlock (tdata->structmutex); - } - templist = templist->next; - } - - gtk_timeout_add (500, update_downloads, NULL); - return (0); } @@ -1331,6 +1582,73 @@ } +gint +update_downloads (gpointer data) +{ + char tempstr[50], temp1str[127]; + GList * templist, * next; + gftp_transfer * tdata; + + if (file_transfer_logs != NULL) + display_cached_logs (); + + if (window2.request->gotbytes != 0) + { + if (window2.request->gotbytes == -1) + { + update_window_info (); + window2.request->gotbytes = 0; + } + else + { + insert_commas (window2.request->gotbytes, tempstr, sizeof (tempstr)); + g_snprintf (temp1str, sizeof (temp1str), + _("Retrieving file names...%s bytes"), tempstr); + gtk_label_set (GTK_LABEL (window2.hoststxt), temp1str); + } + } + + if (viewedit_process_done) + check_done_process (); + + for (templist = file_transfers; templist != NULL;) + { + tdata = templist->data; + if (tdata->ready) + { + pthread_mutex_lock (tdata->structmutex); + + if (tdata->next_file) + on_next_transfer (tdata); + else if (tdata->show) + show_transfer (tdata); + else if (tdata->done) + { + next = templist->next; + transfer_done (templist); + templist = next; + continue; + } + + if (tdata->curfle != NULL) + { + if (!tdata->started && start_file_transfers && + (transfer_in_progress == 0 || !do_one_transfer_at_a_time)) + create_transfer (tdata); + + if (tdata->started) + update_file_status (tdata); + } + pthread_mutex_unlock (tdata->structmutex); + } + templist = templist->next; + } + + gtk_timeout_add (500, update_downloads, NULL); + return (0); +} + + void start_transfer (gpointer data) { @@ -1600,6 +1918,132 @@ } +static void +trans_selectall (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + tdata = data; + + gtk_clist_select_all (GTK_CLIST (tdata->clist)); +} + + +static void +trans_unselectall (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + tdata = data; + + gtk_clist_unselect_all (GTK_CLIST (tdata->clist)); +} + + +static void +overwrite (GtkWidget * widget, gpointer data) +{ + GList * templist, * filelist; + gftp_transfer * tdata; + gftp_file * tempfle; + int curpos; + + tdata = data; + curpos = 0; + filelist = tdata->files; + templist = GTK_CLIST (tdata->clist)->selection; + while (templist != NULL) + { + templist = get_next_selection (templist, &filelist, &curpos); + tempfle = filelist->data; + tempfle->transfer_action = GFTP_TRANS_ACTION_OVERWRITE; + gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Overwrite")); + } +} + + +static void +resume (GtkWidget * widget, gpointer data) +{ + GList * templist, * filelist; + gftp_transfer * tdata; + gftp_file * tempfle; + int curpos; + + tdata = data; + curpos = 0; + filelist = tdata->files; + templist = GTK_CLIST (tdata->clist)->selection; + while (templist != NULL) + { + templist = get_next_selection (templist, &filelist, &curpos); + tempfle = filelist->data; + tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; + gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Resume")); + } +} + + +static void +skip (GtkWidget * widget, gpointer data) +{ + GList * templist, * filelist; + gftp_transfer * tdata; + gftp_file * tempfle; + int curpos; + + tdata = data; + curpos = 0; + filelist = tdata->files; + templist = GTK_CLIST (tdata->clist)->selection; + while (templist != NULL) + { + templist = get_next_selection (templist, &filelist, &curpos); + tempfle = filelist->data; + tempfle->transfer_action = GFTP_TRANS_ACTION_SKIP; + gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Skip")); + } +} + + +static void +ok (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + gftp_file * tempfle; + GList * templist; + + tdata = data; + pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); + for (templist = tdata->files; templist != NULL; templist = templist->next) + { + tempfle = templist->data; + if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) + break; + } + + if (templist == NULL) + { + tdata->show = 0; + tdata->ready = tdata->done = 1; + } + else + tdata->show = tdata->ready = 1; + pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); +} + + +static void +cancel (GtkWidget * widget, gpointer data) +{ + gftp_transfer * tdata; + + tdata = data; + pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); + tdata->show = 0; + tdata->done = tdata->ready = 1; + pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); +} + + void gftp_gtk_ask_transfer (gftp_transfer * tdata) { @@ -1784,488 +2228,3 @@ dialog = NULL; } - -static void -trans_selectall (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - tdata = data; - - gtk_clist_select_all (GTK_CLIST (tdata->clist)); -} - - -static void -trans_unselectall (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - tdata = data; - - gtk_clist_unselect_all (GTK_CLIST (tdata->clist)); -} - - -static void -overwrite (GtkWidget * widget, gpointer data) -{ - GList * templist, * filelist; - gftp_transfer * tdata; - gftp_file * tempfle; - int curpos; - - tdata = data; - curpos = 0; - filelist = tdata->files; - templist = GTK_CLIST (tdata->clist)->selection; - while (templist != NULL) - { - templist = get_next_selection (templist, &filelist, &curpos); - tempfle = filelist->data; - tempfle->transfer_action = GFTP_TRANS_ACTION_OVERWRITE; - gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Overwrite")); - } -} - - -static void -resume (GtkWidget * widget, gpointer data) -{ - GList * templist, * filelist; - gftp_transfer * tdata; - gftp_file * tempfle; - int curpos; - - tdata = data; - curpos = 0; - filelist = tdata->files; - templist = GTK_CLIST (tdata->clist)->selection; - while (templist != NULL) - { - templist = get_next_selection (templist, &filelist, &curpos); - tempfle = filelist->data; - tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; - gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Resume")); - } -} - - -static void -skip (GtkWidget * widget, gpointer data) -{ - GList * templist, * filelist; - gftp_transfer * tdata; - gftp_file * tempfle; - int curpos; - - tdata = data; - curpos = 0; - filelist = tdata->files; - templist = GTK_CLIST (tdata->clist)->selection; - while (templist != NULL) - { - templist = get_next_selection (templist, &filelist, &curpos); - tempfle = filelist->data; - tempfle->transfer_action = GFTP_TRANS_ACTION_SKIP; - gtk_clist_set_text (GTK_CLIST (tdata->clist), curpos, 3, _("Skip")); - } -} - - -static void -ok (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - gftp_file * tempfle; - GList * templist; - - tdata = data; - pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); - for (templist = tdata->files; templist != NULL; templist = templist->next) - { - tempfle = templist->data; - if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP) - break; - } - - if (templist == NULL) - { - tdata->show = 0; - tdata->ready = tdata->done = 1; - } - else - tdata->show = tdata->ready = 1; - pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); -} - - -static void -cancel (GtkWidget * widget, gpointer data) -{ - gftp_transfer * tdata; - - tdata = data; - pthread_mutex_lock ((pthread_mutex_t *) tdata->structmutex); - tdata->show = 0; - tdata->done = tdata->ready = 1; - pthread_mutex_unlock ((pthread_mutex_t *) tdata->structmutex); -} - - -static void -gftp_gtk_calc_kbs (gftp_transfer * tdata, ssize_t num_read) -{ - unsigned long waitusecs; - double difftime, curkbs; - gftp_file * tempfle; - struct timeval tv; - unsigned long toadd; - - gettimeofday (&tv, NULL); - pthread_mutex_lock (tdata->statmutex); - - tempfle = tdata->curfle->data; - tdata->trans_bytes += num_read; - tdata->curtrans += num_read; - tdata->stalled = 0; - - difftime = (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0); - if (difftime <= 0) - tdata->kbs = (double) tdata->trans_bytes / 1024.0; - else - tdata->kbs = (double) tdata->trans_bytes / 1024.0 / difftime; - - difftime = (tv.tv_sec - tdata->lasttime.tv_sec) + ((double) (tv.tv_usec - tdata->lasttime.tv_usec) / 1000000.0); - - if (difftime <= 0) - curkbs = (double) (num_read / 1024.0); - else - curkbs = (double) (num_read / 1024.0 / difftime); - - if (tdata->fromreq->maxkbs > 0 && - curkbs > tdata->fromreq->maxkbs) - { - waitusecs = (double) num_read / 1024.0 / tdata->fromreq->maxkbs * 1000000.0 - difftime; - - if (waitusecs > 0) - { - pthread_mutex_unlock (tdata->statmutex); - difftime += ((double) waitusecs / 1000000.0); - usleep (waitusecs); - pthread_mutex_lock (tdata->statmutex); - } - } - - /* I don't call gettimeofday (&tdata->lasttime) here because this will use - less system resources. This will be close enough for what we need */ - difftime += tdata->lasttime.tv_usec / 1000000.0; - toadd = (long) difftime; - difftime -= toadd; - tdata->lasttime.tv_sec += toadd; - tdata->lasttime.tv_usec = difftime * 1000000.0; - - pthread_mutex_unlock (tdata->statmutex); -} - - -static void -check_done_process (void) -{ - gftp_viewedit_data * ve_proc; - GList * curdata, *deldata; - struct stat st; - int ret; - char *str; - pid_t pid; - - viewedit_process_done = 0; - while ((pid = waitpid (-1, &ret, WNOHANG)) > 0) - { - curdata = viewedit_processes; - while (curdata != NULL) - { - ve_proc = curdata->data; - deldata = curdata; - curdata = curdata->next; - if (ve_proc->pid == pid) - { - viewedit_processes = g_list_remove_link (viewedit_processes, - deldata); - if (ret != 0) - ftp_log (gftp_logging_error, NULL, - _("Error: Child %d returned %d\n"), pid, ret); - else - ftp_log (gftp_logging_misc, NULL, - _("Child %d returned successfully\n"), pid); - - if (!ve_proc->view && !ve_proc->dontupload) - { - /* We was editing the file. Upload it */ - if (stat (ve_proc->filename, &st) == -1) - ftp_log (gftp_logging_error, NULL, - _("Error: Cannot get information about file %s: %s\n"), - ve_proc->filename, g_strerror (errno)); - else if (st.st_mtime == ve_proc->st.st_mtime) - { - ftp_log (gftp_logging_misc, NULL, - _("File %s was not changed\n"), - ve_proc->filename); - remove_file (ve_proc->filename); - } - else - { - memcpy (&ve_proc->st, &st, sizeof (ve_proc->st)); - str = g_strdup_printf ( - _("File %s has changed.\nWould you like to upload it?"), - ve_proc->remote_filename); - - MakeYesNoDialog (_("Edit File"), str, - do_upload, ve_proc, - dont_upload, ve_proc); - g_free (str); - continue; - } - } - - free_edit_data (ve_proc); - continue; - } - } - } -} - - -static void -do_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) -{ - gftp_file * tempfle; - GList * newfile; - - tempfle = g_malloc0 (sizeof (*tempfle)); - tempfle->destfile = ve_proc->remote_filename; - ve_proc->remote_filename = NULL; - tempfle->file = ve_proc->filename; - ve_proc->filename = NULL; - tempfle->done_rm = 1; - newfile = g_list_append (NULL, tempfle); - add_file_transfer (ve_proc->fromwdata->request, ve_proc->towdata->request, - ve_proc->fromwdata, ve_proc->towdata, newfile, 1); - free_edit_data (ve_proc); -} - - -static void -dont_upload (gftp_viewedit_data * ve_proc, gftp_dialog_data * ddata) -{ - remove_file (ve_proc->filename); - free_edit_data (ve_proc); -} - - -static void -free_edit_data (gftp_viewedit_data * ve_proc) -{ - int i; - - if (ve_proc->filename) - g_free (ve_proc->filename); - if (ve_proc->remote_filename) - g_free (ve_proc->remote_filename); - for (i = 0; ve_proc->argv[i] != NULL; i++) - g_free (ve_proc->argv[i]); - g_free (ve_proc->argv); - g_free (ve_proc); -} - - -static int -get_status (gftp_transfer * tdata, ssize_t num_read) -{ - gftp_file * tempfle; - struct timeval tv; - - pthread_mutex_lock (tdata->structmutex); - if (tdata->curfle == NULL) - { - pthread_mutex_unlock (tdata->structmutex); - return (-1); - } - tempfle = tdata->curfle->data; - pthread_mutex_unlock (tdata->structmutex); - - gftp_disconnect (tdata->fromreq); - gftp_disconnect (tdata->toreq); - if (num_read < 0 || tdata->skip_file) - { - if (tdata->fromreq->retries != 0 && tdata->current_file_retries >= tdata->fromreq->retries) - { - tdata->fromreq->logging_function (gftp_logging_error, - tdata->fromreq->user_data, - _("Error: Remote site %s disconnected. Max retries reached...giving up\n"), - tdata->fromreq->hostname != NULL ? - tdata->fromreq->hostname : tdata->toreq->hostname); - return (-1); - } - else - { - tdata->fromreq->logging_function (gftp_logging_error, - tdata->fromreq->user_data, - _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"), - tdata->fromreq->hostname != NULL ? - tdata->fromreq->hostname : tdata->toreq->hostname, - tdata->fromreq->sleep_time); - } - - while (tdata->fromreq->retries == 0 || - tdata->current_file_retries <= tdata->fromreq->retries) - { - if (!tdata->skip_file) - { - tv.tv_sec = tdata->fromreq->sleep_time; - tv.tv_usec = 0; - select (0, NULL, NULL, NULL, &tv); - } - - if (gftp_connect (tdata->fromreq) == 0 && - gftp_connect (tdata->toreq) == 0) - { - pthread_mutex_lock (tdata->structmutex); - tdata->resumed_bytes = tdata->resumed_bytes + tdata->trans_bytes - tdata->curresumed - tdata->curtrans; - tdata->trans_bytes = 0; - if (tdata->skip_file) - { - tdata->total_bytes -= tempfle->size; - tdata->curtrans = 0; - - tdata->curfle = tdata->curfle->next; - tdata->next_file = 1; - tdata->skip_file = 0; - tdata->cancel = 0; - tdata->fromreq->cancel = 0; - tdata->toreq->cancel = 0; - } - else - { - tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME; - tempfle->startsize = tdata->curtrans + tdata->curresumed; - /* We decrement this here because it will be incremented in - the loop again */ - tdata->curresumed = 0; - tdata->current_file_number--; /* Decrement this because it - will be incremented when we - continue in the loop */ - } - gettimeofday (&tdata->starttime, NULL); - pthread_mutex_unlock (tdata->structmutex); - return (1); - } - else - tdata->current_file_retries++; - } - } - else if (tdata->cancel) - return (-1); - - return (0); -} - - -static void -wakeup_main_thread (gpointer data, gint source, GdkInputCondition condition) -{ - gftp_request * request; - char c; - - request = data; - if (request->wakeup_main_thread[0] > 0) - read (request->wakeup_main_thread[0], &c, 1); -} - - -static gint -setup_wakeup_main_thread (gftp_request * request) -{ - gint handler; - - if (socketpair (AF_UNIX, SOCK_STREAM, 0, request->wakeup_main_thread) == 0) - { - /* FIXME - depreciated in GDK 2.0 */ - handler = gdk_input_add (request->wakeup_main_thread[0], - GDK_INPUT_READ, wakeup_main_thread, request); - } - else - { - request->wakeup_main_thread[0] = 0; - request->wakeup_main_thread[1] = 0; - handler = 0; - } - return (handler); -} - - -static void -teardown_wakeup_main_thread (gftp_request * request, gint handler) -{ - if (request->wakeup_main_thread[0] > 0 && request->wakeup_main_thread[1] > 0) - { - /* FIXME - depreciated in GDK 2.0 */ - gdk_input_remove (handler); - close (request->wakeup_main_thread[0]); - close (request->wakeup_main_thread[1]); - request->wakeup_main_thread[0] = 0; - request->wakeup_main_thread[1] = 0; - } -} - - -static mode_t -parse_attribs (char *attribs) -{ - mode_t mode; - int cur; - - cur = 0; - if (attribs[1] == 'r') - cur += 4; - if (attribs[2] == 'w') - cur += 2; - if (attribs[3] == 'x' || - attribs[3] == 's') - cur += 1; - mode = cur; - - cur = 0; - if (attribs[4] == 'r') - cur += 4; - if (attribs[5] == 'w') - cur += 2; - if (attribs[6] == 'x' || - attribs[6] == 's') - cur += 1; - mode = (mode * 10) + cur; - - cur = 0; - if (attribs[7] == 'r') - cur += 4; - if (attribs[8] == 'w') - cur += 2; - if (attribs[9] == 'x' || - attribs[9] == 's') - cur += 1; - mode = (mode * 10) + cur; - - return (mode); -} - - -static void -remove_file (char *filename) -{ - if (unlink (filename) == 0) - ftp_log (gftp_logging_misc, NULL, _("Successfully removed %s\n"), - filename); - else - ftp_log (gftp_logging_error, NULL, - _("Error: Could not remove file %s: %s\n"), filename, - g_strerror (errno)); -} - diff -r eec25f215772 -r e5f6054590b5 src/gtk/view_dialog.c --- a/src/gtk/view_dialog.c Tue Nov 05 20:36:11 2002 +0000 +++ b/src/gtk/view_dialog.c Wed Nov 06 02:20:25 2002 +0000 @@ -20,15 +20,6 @@ #include "gftp-gtk.h" static const char cvsid[] = "$Id$"; -static gftp_viewedit_data * fork_process ( char *proc, - char *filename, - int fd, - char *remote_filename, - int viewedit, - int del_file, - int dontupload, - gftp_window_data * wdata ); - static gftp_file * curfle; void @@ -162,6 +153,81 @@ } +static gftp_viewedit_data * +fork_process (char *proc, char *filename, int fd, char *remote_filename, + int viewedit, int del_file, int dontupload, + gftp_window_data * wdata) +{ + gftp_viewedit_data * newproc; + char *pos, *endpos, **argv; + pid_t ret; + int n; + + argv = NULL; + n = 0; + pos = proc; + while ((endpos = strchr (pos, ' ')) != NULL) + { + *endpos = '\0'; + n++; + argv = g_realloc (argv, n * sizeof (char *)); + argv[n - 1] = g_malloc (strlen (pos) + 1); + strcpy (argv[n - 1], pos); + *endpos = ' '; + pos = endpos + 1; + } + argv = g_realloc (argv, (n + 3) * sizeof (char *)); + argv[n] = g_malloc (strlen (pos) + 1); + strcpy (argv[n], pos); + argv[n + 1] = g_malloc (strlen (filename) + 1); + strcpy (argv[n + 1], filename); + argv[n + 2] = NULL; + + newproc = NULL; + switch ((ret = fork ())) + { + case 0: + close (fd); + execvp (argv[0], argv); + _exit (1); + case -1: + for (n = 0; argv[n] != NULL; n++) + g_free (argv[n]); + ftp_log (gftp_logging_error, NULL, + _("View: Cannot fork another process: %s\n"), g_strerror (errno)); + break; + default: + ftp_log (gftp_logging_misc, NULL, _("Running program: %s %s\n"), proc, + filename); + newproc = g_malloc0 (sizeof (*newproc)); + newproc->pid = ret; + newproc->argv = argv; + if (wdata == &window2) + { + newproc->fromwdata = &window2; + newproc->towdata = &window1; + } + else + { + newproc->fromwdata = &window1; + newproc->towdata = &window2; + } + newproc->filename = g_malloc (strlen (filename) + 1); + strcpy (newproc->filename, filename); + if (remote_filename != NULL) + { + newproc->remote_filename = g_malloc (strlen (remote_filename) + 1); + strcpy (newproc->remote_filename, remote_filename); + } + newproc->view = viewedit; + newproc->rm = del_file; + newproc->dontupload = dontupload; + viewedit_processes = g_list_append (viewedit_processes, newproc); + } + return (newproc); +} + + void view_file (char *filename, int fd, int viewedit, int del_file, int start_pos, int dontupload, char *remote_filename, gftp_window_data * wdata) @@ -348,78 +414,3 @@ gtk_adjustment_set_value (vadj, vadj->upper); } - -static gftp_viewedit_data * -fork_process (char *proc, char *filename, int fd, char *remote_filename, - int viewedit, int del_file, int dontupload, - gftp_window_data * wdata) -{ - gftp_viewedit_data * newproc; - char *pos, *endpos, **argv; - pid_t ret; - int n; - - argv = NULL; - n = 0; - pos = proc; - while ((endpos = strchr (pos, ' ')) != NULL) - { - *endpos = '\0'; - n++; - argv = g_realloc (argv, n * sizeof (char *)); - argv[n - 1] = g_malloc (strlen (pos) + 1); - strcpy (argv[n - 1], pos); - *endpos = ' '; - pos = endpos + 1; - } - argv = g_realloc (argv, (n + 3) * sizeof (char *)); - argv[n] = g_malloc (strlen (pos) + 1); - strcpy (argv[n], pos); - argv[n + 1] = g_malloc (strlen (filename) + 1); - strcpy (argv[n + 1], filename); - argv[n + 2] = NULL; - - newproc = NULL; - switch ((ret = fork ())) - { - case 0: - close (fd); - execvp (argv[0], argv); - _exit (1); - case -1: - for (n = 0; argv[n] != NULL; n++) - g_free (argv[n]); - ftp_log (gftp_logging_error, NULL, - _("View: Cannot fork another process: %s\n"), g_strerror (errno)); - break; - default: - ftp_log (gftp_logging_misc, NULL, _("Running program: %s %s\n"), proc, - filename); - newproc = g_malloc0 (sizeof (*newproc)); - newproc->pid = ret; - newproc->argv = argv; - if (wdata == &window2) - { - newproc->fromwdata = &window2; - newproc->towdata = &window1; - } - else - { - newproc->fromwdata = &window1; - newproc->towdata = &window2; - } - newproc->filename = g_malloc (strlen (filename) + 1); - strcpy (newproc->filename, filename); - if (remote_filename != NULL) - { - newproc->remote_filename = g_malloc (strlen (remote_filename) + 1); - strcpy (newproc->remote_filename, remote_filename); - } - newproc->view = viewedit; - newproc->rm = del_file; - newproc->dontupload = dontupload; - viewedit_processes = g_list_append (viewedit_processes, newproc); - } - return (newproc); -} -