static void gtkutil_check_file (char *file, struct file_req *freq) { struct stat st; int axs = FALSE; char temp[256]; path_part (file, temp, sizeof (temp)); /* check if the file is readable or writable */ if (freq->flags & FRF_WRITE) { if (access (temp, W_OK) == 0) axs = TRUE; } else { if (stat (file, &st) != -1) { if (!S_ISDIR (st.st_mode) || (freq->flags & FRF_CHOOSEFOLDER)) axs = TRUE; } } if (axs) { char *utf8_file; /* convert to UTF8. It might be converted back to locale by server.c's g_convert */ utf8_file = hexchat_filename_to_utf8 (file, -1, NULL, NULL, NULL); if (utf8_file) { freq->callback (freq->userdata, utf8_file); g_free (utf8_file); } else { fe_message ("Filename encoding is corrupt.", FE_MSG_ERROR); } } else { if (freq->flags & FRF_WRITE) fe_message (_("Cannot write to that file."), FE_MSG_ERROR); else fe_message (_("Cannot read that file."), FE_MSG_ERROR); } }
void gtkutil_file_req (const char *title, void *callback, void *userdata, char *filter, char *extensions, int flags) { struct file_req *freq; GtkWidget *dialog; GtkFileFilter *filefilter; extern char *get_xdir_fs (void); char *token; char *tokenbuffer; #if 0 /* native file dialogs */ #ifdef WIN32 if (!(flags & FRF_WRITE)) { freq = malloc (sizeof (struct file_req)); freq->th = thread_new (); freq->flags = 0; freq->multiple = (flags & FRF_MULTIPLE); freq->callback = callback; freq->userdata = userdata; freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0); if (!filter) { freq->filter = "All files\0*.*\0" "Executables\0*.exe\0" "ZIP files\0*.zip\0\0"; } else { freq->filter = filter; } thread_start (freq->th, win32_thread, freq); fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq); return; } else { freq = malloc (sizeof (struct file_req)); freq->th = thread_new (); freq->flags = 0; freq->multiple = (flags & FRF_MULTIPLE); freq->callback = callback; freq->userdata = userdata; freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0); if (!filter) { freq->filter = "All files\0*.*\0\0"; } else { freq->filter = filter; } thread_start (freq->th, win32_thread2, freq); fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq); return; } #endif #endif if (flags & FRF_WRITE) { dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); if (filter && filter[0]) /* filter becomes initial name when saving */ { char temp[1024]; path_part (filter, temp, sizeof (temp)); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), temp); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), file_part (filter)); } if (!(flags & FRF_NOASKOVERWRITE)) gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); } else dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); if (flags & FRF_MULTIPLE) gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); if (last_dir[0]) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir); if (flags & FRF_ADDFOLDER) gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), get_xdir_fs (), NULL); if (flags & FRF_CHOOSEFOLDER) { gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), filter); } else { if (filter && (flags & FRF_FILTERISINITIAL)) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), filter); } if (flags & FRF_EXTENSIONS && extensions != NULL) { filefilter = gtk_file_filter_new (); tokenbuffer = g_strdup (extensions); token = strtok (tokenbuffer, ";"); while (token != NULL) { gtk_file_filter_add_pattern (filefilter, token); token = strtok (NULL, ";"); } g_free (tokenbuffer); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filefilter); } freq = malloc (sizeof (struct file_req)); freq->dialog = dialog; freq->flags = flags; freq->callback = callback; freq->userdata = userdata; g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtkutil_file_req_response), freq); g_signal_connect (G_OBJECT (dialog), "destroy", G_CALLBACK (gtkutil_file_req_destroy), (gpointer) freq); gtk_widget_show (dialog); }
/* * get_mntinfo - get the mount table, now dynamically allocated. Returns 0 if * no problem and 1 if there's a fatal error. */ int get_mntinfo(int map_client, char *vfstab_file) { static char *rn = "/"; FILE *pp; struct mnttab mtbuf; struct mnttab *mt = &mtbuf; char *install_root; int is_remote; /* * Open the mount table for the current host and establish a global * table that holds data about current mount status. */ if ((pp = setmntent(MOUNT_TABLE, "r")) == NULL) { progerr(ERR_NOTABLE, "mount", MOUNT_TABLE, strerror(errno)); return (1); } /* * First, review the mounted filesystems on the managing host. This * may also be the target host but we haven't decided that for sure * yet. */ while (!getmntent(pp, mt)) if (construct_mt(mt)) return (1); (void) endmntent(pp); /* * Now, we see if this installation is to a client. If it is, we scan * the client's vfstab to determine what filesystems are * inappropriate to write to. This simply adds the vfstab entries * representing what will be remote file systems for the client. * Everything that isn't remote to the client is already accounted * for in the fs_tab[] so far. If the remote filesystem is really on * this server, we will write through to the server from this client. */ install_root = get_inst_root(); if (install_root && strcmp(install_root, "/") != 0 && map_client) { /* OK, this is a legitimate remote client. */ struct vfstab vfsbuf; struct vfstab *vfs = &vfsbuf; char VFS_TABLE[PATH_MAX]; /* * Since we use the fsys() function later, and it depends on * an ordered list, we have to sort the list here. */ qsort(fs_tab, fs_tab_used, sizeof (struct fstable *), fs_tab_ent_comp); /* * Here's where the vfstab for the target is. If we can get * to it, we'll scan it for what the client will see as * remote filesystems, otherwise, we'll just skip this. */ if (vfstab_file) { (void) snprintf(VFS_TABLE, sizeof (VFS_TABLE), "%s", vfstab_file); } else { (void) snprintf(VFS_TABLE, sizeof (VFS_TABLE), "%s%s", install_root, VFSTAB); } if (access(VFS_TABLE, R_OK) == 0) { char *link_name; /* * Open the vfs table for the target host. */ if ((pp = setmntent(VFS_TABLE, "r")) == NULL) { progerr(ERR_NOTABLE, "vfs", VFS_TABLE, strerror(errno)); return (1); } /* Do this for each entry in the vfstab. */ while (!getvfsent(pp, vfs)) { char client_mountp[PATH_MAX]; int mnt_stat; /* * We put it into the fs table if it's * remote mounted (even from this server) or * loopback mounted from the client's point * of view. */ if (!(is_remote = is_remote_src(vfs->vfs_special)) && strcmp(vfs->vfs_fstype, MNTTYPE_LOFS) != 0) continue; /* not interesting */ /* * Construct client_mountp by prepending the * install_root to the 'mount point' name. */ if (strcmp(vfs->vfs_mountp, "/") == 0) { (void) strcpy(client_mountp, install_root); } else { (void) snprintf(client_mountp, sizeof (client_mountp), "%s%s", install_root, vfs->vfs_mountp); } /* * We also skip the entry if the vfs_special * path and the client_path are the same. * There's no need to mount it, it's just a * cachefs optimization that mounts a * directory over itself from this server. */ if ((is_remote == SELF_SERVE) && strcmp(path_part(vfs->vfs_special), client_mountp) == 0) continue; /* Determine if this is already mounted. */ link_name = strdup(path_part(vfs->vfs_special)); mnt_stat = already_mounted(vfs, (is_remote != REAL_REMOTE), client_mountp, link_name); if (mnt_stat == MNT_EXACT) { mod_existing(vfs, match_mount, is_remote); } else { /* MNT_NOT */ if (construct_vfs(vfs, client_mountp, link_name, is_remote, mnt_stat)) { return (1); } } } (void) endmntent(pp); } /* end of if(access()) */ } /* end of if(install_root) */ /* This next one may look stupid, but it can really happen. */ if (fs_tab_used <= 0) { progerr(ERR_MNT_NOMOUNTS); return (1); } /* * Now that we have the complete list of mounted (or virtually * mounted) filesystems, we sort the mountpoints in reverse order * based on the length of the 'mount point' name. */ qsort(fs_tab, fs_tab_used, sizeof (struct fstable *), fs_tab_ent_comp); if (strcmp(fs_tab[fs_tab_used-1]->name, rn) != 0) { progerr(ERR_MNT_NOROOT, fs_tab[fs_tab_used-1]->name, rn, errno, strerror(errno)); return (1); } else { return (0); } }
void gtkutil_file_req (const char *title, void *callback, void *userdata, char *filter, char *extensions, int flags) { struct file_req *freq; GtkWidget *dialog; GtkFileFilter *filefilter; extern char *get_xdir_fs (void); char *token; char *tokenbuffer; #if 0 /* native file dialogs */ #ifdef WIN32 if (!(flags & FRF_WRITE)) { freq = malloc (sizeof (struct file_req)); freq->th = thread_new (); freq->flags = 0; freq->multiple = (flags & FRF_MULTIPLE); freq->callback = callback; freq->userdata = userdata; freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0); if (!filter) { freq->filter = "All files\0*.*\0" "Executables\0*.exe\0" "ZIP files\0*.zip\0\0"; } else { freq->filter = filter; } thread_start (freq->th, win32_thread, freq); fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq); return; } else { freq = malloc (sizeof (struct file_req)); freq->th = thread_new (); freq->flags = 0; freq->multiple = (flags & FRF_MULTIPLE); freq->callback = callback; freq->userdata = userdata; freq->title = g_locale_from_utf8 (title, -1, 0, 0, 0); if (!filter) { freq->filter = "All files\0*.*\0\0"; } else { freq->filter = filter; } thread_start (freq->th, win32_thread2, freq); fe_input_add (freq->th->pipe_fd[0], FIA_FD|FIA_READ, win32_read_thread, freq); return; } #endif #endif if (flags & FRF_WRITE) { dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); if (filter && filter[0]) /* filter becomes initial name when saving */ { char temp[1024]; path_part (filter, temp, sizeof (temp)); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), temp); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), file_part (filter)); } if (!(flags & FRF_NOASKOVERWRITE)) gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); } else dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); if (flags & FRF_MULTIPLE) gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); if (last_dir[0]) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir); if (flags & FRF_ADDFOLDER) gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), get_xdir (), NULL); if (flags & FRF_CHOOSEFOLDER) { gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), filter); } else { if (filter && (flags & FRF_FILTERISINITIAL)) { gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), filter); } /* With DCC, we can't rely on filter as initial folder since filter already contains * the filename upon DCC RECV. Thus we have no better option than to check for the message * which will be the title of the window. For DCC it always contains the "offering" word. * This method is really ugly but it works so we'll stick with it for now. */ else if (strstr (title, "offering") != NULL) { gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), prefs.hex_dcc_dir); } /* by default, open the config folder */ else { gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), get_xdir ()); } } if (flags & FRF_EXTENSIONS && extensions != NULL) { filefilter = gtk_file_filter_new (); tokenbuffer = g_strdup (extensions); token = strtok (tokenbuffer, ";"); while (token != NULL) { gtk_file_filter_add_pattern (filefilter, token); token = strtok (NULL, ";"); } g_free (tokenbuffer); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filefilter); } freq = malloc (sizeof (struct file_req)); freq->dialog = dialog; freq->flags = flags; freq->callback = callback; freq->userdata = userdata; g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtkutil_file_req_response), freq); g_signal_connect (G_OBJECT (dialog), "destroy", G_CALLBACK (gtkutil_file_req_destroy), (gpointer) freq); gtk_widget_show (dialog); }
void gtkutil_file_req (const char *title, void *callback, void *userdata, char *filter, char *extensions, int flags) { struct file_req *freq; GtkWidget *dialog; GtkFileFilter *filefilter; extern char *get_xdir_fs (void); char *token; char *tokenbuffer; if (flags & FRF_WRITE) { dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); if (!(flags & FRF_NOASKOVERWRITE)) gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); } else dialog = gtk_file_chooser_dialog_new (title, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); if (filter && filter[0] && (flags & FRF_FILTERISINITIAL)) { if (flags & FRF_WRITE) { char temp[1024]; path_part (filter, temp, sizeof (temp)); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), temp); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), file_part (filter)); } else gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), filter); } else if (!(flags & FRF_RECENTLYUSED)) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), get_xdir ()); if (flags & FRF_MULTIPLE) gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); if (flags & FRF_CHOOSEFOLDER) gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); if ((flags & FRF_EXTENSIONS || flags & FRF_MIMETYPES) && extensions != NULL) { filefilter = gtk_file_filter_new (); tokenbuffer = g_strdup (extensions); token = strtok (tokenbuffer, ";"); while (token != NULL) { if (flags & FRF_EXTENSIONS) gtk_file_filter_add_pattern (filefilter, token); else gtk_file_filter_add_mime_type (filefilter, token); token = strtok (NULL, ";"); } g_free (tokenbuffer); gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filefilter); } gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), get_xdir (), NULL); freq = malloc (sizeof (struct file_req)); freq->dialog = dialog; freq->flags = flags; freq->callback = callback; freq->userdata = userdata; g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtkutil_file_req_response), freq); g_signal_connect (G_OBJECT (dialog), "destroy", G_CALLBACK (gtkutil_file_req_destroy), (gpointer) freq); gtk_widget_show (dialog); }