/* Copyright (C) Rafal Metkowski This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fd_xftp.h" #define ASCII 0 #define BIN 1 #define LOCAL 0 #define REMOTE 1 #define BY_NAME 1 #define BY_SIZE 2 #define BUF_SIZE 32767 #define HIST_SIZE 15 #define MAXLINE 512 #define CANCEL 0 #define OVERWRITE 1 #define RESUME_TRANSF 2 #define N_FORMS 17 FD_fd_main *fm; FD_fd_conn_par *fcp; FD_fd_bookmarks *fb; FD_fd_options *fo; FD_fd_options_net *fon; FD_fd_options_fonts *fof; FD_fd_options_files *fofl; FD_fd_options_colors *foc; FD_fd_about *fa; FD_fd_download *fd; FD_fd_download_question *fdq; FD_fd_input *fi; FD_fd_question *fq; FD_fd_message *fmsg; FD_fd_remote_view *frv; FD_fd_local_view *flv; FD_fd_colors *fc; struct dir_item { char *file_name; char *link_name; char *path; long mode; long file_size; time_t modif_time; struct dir_item *next; int selected; } **local_files = NULL, **remote_files = NULL, *buffer_list = NULL; struct hist_item { char *address; char *user_name; char *pass_unenc; char *local_dir; char *remote_dir; int anonym_login; struct hist_item *next; } *hist_first = NULL, *hist_last = NULL; struct addr_item { char *address; char *dir; struct addr_item *next; } *bookm_first = NULL, *bookm_last = NULL; struct dir_buf_item { char *dir_path; struct dir_item **dir; int dir_len; int top; struct dir_buf_item *next; } *dir_buf = NULL, *cur_dir = NULL; char *user_name = NULL, *pass_enc = NULL, *pass_unenc = NULL, *address = NULL; char *remote_dir_path_inp = NULL, *local_dir_path_inp = NULL, e_mail[81] = ""; char *remote_dir_path = NULL, *home_dir, *opt_file_name, *hist_file_name; char *log_file_name, *addr_file_name, *std_bookm_file, dir_col[10], lnk_col[10], exe_col[10], other_col[10]; int con_opened = 0, busy = 0, aborted = 0, anonym_login = 0, con_canceled = 0; int type = BIN, cur_type = ASCII, font_size = 10, br_fsize = 10, port = 21; int sock_servPI, sock_userDTP, sock_servDTP; int n_local = 0, n_remote = 0, n_buffer = 0, n_hist = 0, sort_key_local = BY_NAME, sort_key_remote = BY_NAME; int ninteract = 0, show_hidden_local = 1, show_hidden_remote = 1, sys_unix, passive = 0, f_fold_hidden = 0; int minx = 670, miny = 400; struct sockaddr_in serverPI, userDTP; FL_FORM *forms[N_FORMS]; FILE *flog; int send_command(const char *command, const char *arg, char **pReply); int get_reply(char **pReply); int data_command(const char *command, const char *arg); void cb_close(FL_OBJECT * ob, long arg); void cb_remote_view_ok(FL_OBJECT * ob, long arg); char *get_cwdir(); void sort(struct dir_item **ppFiles, int iFiles, int key); void read_bookmarks(const char *bookm_file); void write_bookmarks(); void read_hist(); FL_CALLBACKPTR cb_old_local, cb_old_remote, cb_old_buffer; char * cut(const char *fn) { char *cutted; cutted = malloc(25); strncpy(cutted, fn, 20); cutted[20] = '\0'; if (strlen(fn) > 20) memset(cutted + 17, '.', 3); return cutted; } char * resolve_link(const char *full_name) { char *resolved, *pc1; resolved = malloc(strlen(full_name) + 1); strcpy(resolved, full_name); pc1 = strstr(resolved, "->"); if (pc1 == NULL) { free(resolved); return NULL; } *--pc1 = '\0'; return resolved; } void center_downl() { int x, y; x = fm->fd_main->x + (fm->fd_main->w - fd->fd_download->w) / 2; y = fm->fd_main->y + (fm->fd_main->h - fd->fd_download->h) / 2; fl_set_form_position(fd->fd_download, x, y); } int prehndl_local(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { if (event == FL_MOTION || event == FL_MOUSE) fl_set_browser_topline(fm->br_local_size, fl_get_browser_topline(ob)); return 0; } int prehndl_local_size(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { if (event == FL_MOTION || event == FL_MOUSE) fl_set_browser_topline(fm->br_local, fl_get_browser_topline(ob)); return 0; } int prehndl_remote(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { if (event == FL_MOTION || event == FL_MOUSE) fl_set_browser_topline(fm->br_remote_size, fl_get_browser_topline(ob)); return 0; } int prehndl_remote_size(FL_OBJECT * ob, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { if (event == FL_MOTION || event == FL_MOUSE) fl_set_browser_topline(fm->br_remote, fl_get_browser_topline(ob)); return 0; } void cb_vscroll_local(FL_OBJECT * ob, long arg) { int i; cb_old_local(ob, arg); i = fl_get_browser_topline(fm->br_local_size); fl_set_browser_topline(fm->br_local, i); } void cb_vscroll_remote(FL_OBJECT * ob, long arg) { int i; cb_old_remote(ob, arg); i = fl_get_browser_topline(fm->br_remote_size); fl_set_browser_topline(fm->br_remote, i); } void add_to_log (const char *line) { if (!ninteract) fl_addto_browser (fm->br_log, line); if (flog != NULL) fprintf (flog, "%s\n", line); } void add_to_log_err(const char *func) { const char *estr = strerror(errno); if (!ninteract) { fl_addto_browser_chars(fm->br_log, func); fl_addto_browser_chars(fm->br_log, ":"); fl_addto_browser_chars(fm->br_log, estr); } if (flog != NULL) { fprintf(flog, "%s:", func); fprintf(flog, "%s\n", estr); } } void check_forms() { if (!ninteract) fl_check_forms(); } int cmp_name(const void *p1, const void *p2) { struct dir_item *pF1 = *((struct dir_item **) p1); struct dir_item *pF2 = *((struct dir_item **) p2); if (S_ISDIR(pF1->mode) && !S_ISDIR(pF2->mode)) return -1; if (S_ISDIR(pF2->mode) && !S_ISDIR(pF1->mode)) return 1; if (S_ISLNK(pF1->mode) && !S_ISLNK(pF2->mode)) return -1; if (S_ISLNK(pF2->mode) && !S_ISLNK(pF1->mode)) return 1; if (strcmp(pF1->file_name, "..") == 0) return -1; if (strcmp(pF2->file_name, "..") == 0) return 1; return strcmp(pF1->file_name, pF2->file_name); } int cmp_size(const void *p1, const void *p2) { struct dir_item *pF1 = *((struct dir_item **) p1); struct dir_item *pF2 = *((struct dir_item **) p2); if (S_ISDIR(pF1->mode) && !S_ISDIR(pF2->mode)) return -1; if (S_ISDIR(pF2->mode) && !S_ISDIR(pF1->mode)) return 1; if (S_ISLNK(pF1->mode) && !S_ISLNK(pF2->mode)) return -1; if (S_ISLNK(pF2->mode) && !S_ISLNK(pF1->mode)) return 1; if (strcmp(pF1->file_name, "..") == 0) return -1; if (strcmp(pF2->file_name, "..") == 0) return 1; if (S_ISLNK(pF1->mode) || S_ISDIR(pF1->mode)) return strcmp(pF1->file_name, pF2->file_name); return pF1->file_size - pF2->file_size; } void activate_form(FL_FORM * form) { FL_OBJECT *p1; if (ninteract) return; p1 = form->first; fl_freeze_form(form); while (1) { if (p1->objclass == FL_BUTTON || p1->objclass == FL_TEXT || p1->objclass == FL_CHECKBUTTON) fl_set_object_lcol(p1, FL_BLACK); if (p1 == form->last) break; p1 = p1->next; } if (!con_opened || busy) { fl_set_object_lcol(fm->remote_btns, FL_INACTIVE); fl_set_object_lcol(fm->br_remote, FL_INACTIVE); fl_set_object_lcol(fm->br_remote_size, FL_INACTIVE); } if (busy) fl_set_object_lcol(fm->local_btns, FL_INACTIVE); fl_unfreeze_form(form); fl_activate_form(form); } void deactivate_form(FL_FORM * form) { FL_OBJECT *p1; if (ninteract) return; p1 = form->first; fl_deactivate_form(form); fl_freeze_form(form); while (1) { if (p1->objclass == FL_BUTTON || p1->objclass == FL_TEXT) fl_set_object_lcol(p1, FL_INACTIVE); if (p1 == form->last) break; p1 = p1->next; } fl_unfreeze_form(form); } void activate_object(FL_OBJECT * ob) { fl_set_object_lcol(ob, FL_BLACK); fl_activate_object(ob); } void deactivate_object(FL_OBJECT * ob) { fl_set_object_lcol(ob, FL_INACTIVE); fl_deactivate_object(ob); } void adjust_path(FL_OBJECT * f_txt, char *path) { int i, path_len, x, y, w, h; char *pc1, *ad_path; fl_get_object_geometry(f_txt, &x, &y, &w, &h); w -= 10; pc1 = path; path_len = strlen(path); for (i = path_len; i > 0; i--) { if (fl_get_string_width(1, font_size, pc1, i) <= w) { ad_path = malloc(strlen(path) + 1); strcpy(ad_path, pc1); if (i != path_len) memset(ad_path, '.', 3); break; } pc1++; } fl_set_object_label(f_txt, ad_path); free(ad_path); } void add_to_history() { char *hist_line; const char *a = fl_get_input(fcp->address); const char *r = fl_get_input(fcp->remote_dir); int i, nh, repeated = 0; struct hist_item *pHist_it, *pPrev_it = NULL; FILE *f_history; read_hist(); pHist_it = hist_first; for (i = 1; pHist_it != NULL; i++) { if (strcmp(pHist_it->address, a) == 0 && strcmp(pHist_it->remote_dir, r) == 0) { repeated = 1; break; } pPrev_it = pHist_it; pHist_it = pHist_it->next; } if (repeated) { if (!ninteract) fl_delete_browser_line(fcp->br_history, i); if (pPrev_it != NULL) { pPrev_it->next = pHist_it->next; pHist_it->next = hist_first; hist_first = pHist_it; free(hist_first->user_name); free(hist_first->pass_unenc); free(hist_first->local_dir); } } else { pHist_it = malloc(sizeof(struct hist_item)); pHist_it->next = hist_first; hist_first = pHist_it; pHist_it->remote_dir = malloc(strlen(r) + 1); strcpy(pHist_it->remote_dir, r); pHist_it->address = malloc(strlen(a) + 1); strcpy(pHist_it->address, a); n_hist++; } hist_line = malloc(strlen(a) + strlen(r) + 5); sprintf(hist_line, "%s %s", a, r); if (!ninteract) fl_insert_browser_line(fcp->br_history, 1, hist_line); free(hist_line); pHist_it->user_name = malloc(strlen(user_name) + 1); strcpy(pHist_it->user_name, user_name); pHist_it->pass_unenc = malloc(strlen(pass_unenc) + 1); strcpy(pHist_it->pass_unenc, pass_unenc); pHist_it->local_dir = malloc(strlen(local_dir_path_inp) + 1); strcpy(pHist_it->local_dir, local_dir_path_inp); pHist_it->anonym_login = anonym_login; if ((f_history = fopen(hist_file_name, "w")) != NULL) { nh = n_hist > HIST_SIZE ? HIST_SIZE : n_hist; fprintf(f_history, "%d\n", nh); pHist_it = hist_first; for (i = 0; i < nh; i++) { fprintf(f_history, "%s\n", pHist_it->address); fprintf(f_history, "%s\n", pHist_it->user_name); fprintf(f_history, "%s\n", pHist_it->pass_unenc); fprintf(f_history, "%s\n", pHist_it->local_dir); fprintf(f_history, "%s\n", pHist_it->remote_dir); fprintf(f_history, "%d\n", pHist_it->anonym_login); pHist_it = pHist_it->next; } fclose(f_history); } } void add_file_to_list(struct dir_item **lf, char *fn, long fs, time_t mt, long mode, char *path) { struct dir_item *pDir_it, *last_file; pDir_it = malloc(sizeof(struct dir_item)); pDir_it->next = *lf; last_file = pDir_it; last_file->file_name = malloc(strlen(fn) + 1); strcpy(last_file->file_name, fn); last_file->link_name = resolve_link(fn); last_file->file_size = fs; last_file->modif_time = mt; last_file->mode = mode; last_file->selected = 0; if (path != NULL) { last_file->path = malloc(strlen(path) + 1); strcpy(last_file->path, path); } else last_file->path = NULL; *lf = last_file; } struct dir_item ** put_files_into_array(struct dir_item *last_file, int iFiles) { int i; struct dir_item **ppDir_it, **ppFiles; ppFiles = malloc(iFiles * sizeof(struct dir_item *)); ppDir_it = ppFiles + iFiles; for (i = 0; i < iFiles; i++) { *--ppDir_it = last_file; last_file = last_file->next; } return ppFiles; } void remove_file_from_array(struct dir_item ***pppFiles, int *piFiles, int iFileno) { int i; struct dir_item **ppF1, **ppF2, **ppNew_files; ppNew_files = malloc(--*piFiles * sizeof(struct dir_item *)); ppF1 = *pppFiles; ppF2 = ppNew_files; for (i = 0; i < *piFiles; i++) { if (i == iFileno) ppF1++; *(ppF2++) = *(ppF1++); } free(*pppFiles); *pppFiles = ppNew_files; } void add_file_to_array(struct dir_item ***pppFiles, int *piFiles, const char *fn, long fs, time_t mt, long mode) { int i; struct dir_item **ppF1, **ppF2, **ppNewfiles, *pNew_file; ppNewfiles = malloc((*piFiles + 1) * sizeof(struct dir_item *)); ppF1 = *pppFiles; ppF2 = ppNewfiles; for (i = 0; i < *piFiles; i++) *(ppF2++) = *(ppF1++); pNew_file = malloc(sizeof(struct dir_item)); pNew_file->file_name = malloc(strlen(fn) + 1); strcpy(pNew_file->file_name, fn); pNew_file->path = NULL; pNew_file->link_name = resolve_link(fn); pNew_file->file_size = fs; pNew_file->modif_time = mt; pNew_file->mode = mode; pNew_file->selected = 0; *ppF2 = pNew_file; free(*pppFiles); *pppFiles = ppNewfiles; (*piFiles)++; } void put_files_into_browser(FL_OBJECT * browser, FL_OBJECT * browser_size, struct dir_item **ppFiles, int iFiles, int sort_key) { int i, j; char *file_name, file_size[30]; fl_clear_browser(browser); fl_clear_browser(browser_size); fl_freeze_form(fm->fd_main); sort(ppFiles, iFiles, sort_key); for (i = 0; i < iFiles; i++) { file_name = malloc(strlen((*ppFiles)->file_name) + 9); switch ((*ppFiles)->mode & S_IFMT) { case S_IFDIR: strcpy(file_name, dir_col); sprintf(file_size, "%s@rDIR", dir_col); break; case S_IFLNK: strcpy(file_name, lnk_col); sprintf(file_size, "%s@rLNK", lnk_col); break; default: if ((*ppFiles)->mode & S_IXUSR) strcpy(file_name, exe_col); else strcpy(file_name, other_col); if ((*ppFiles)->file_size < (long) 1024) sprintf(file_size, "%s@r%li", file_name, (long) (*ppFiles)->file_size); else sprintf(file_size, "%s@r%li k", file_name, (long) (*ppFiles)->file_size >> 10); } strcat(file_name, "@n"); if (*(*ppFiles)->file_name == '@') strcat(file_name, "@"); strcat(file_name, (*ppFiles)->file_name); fl_add_browser_line(browser, file_name); fl_add_browser_line(browser_size, file_size); if ((*ppFiles)->selected) { j = fl_get_browser_maxline(browser); fl_select_browser_line(browser, j); fl_select_browser_line(browser_size, j); } free(file_name); ppFiles++; } fl_unfreeze_form(fm->fd_main); } void read_local_dir() { struct stat stbuf; char *local_dir_path; int i; DIR *pDir; struct dirent *dir_ent; struct dir_item **ppDir_it, *last_file = NULL; fl_clear_browser(fm->br_local); fl_clear_browser(fm->br_local_size); ppDir_it = local_files; for (i = 0; i < n_local; i++) { free((*ppDir_it)->file_name); free((*ppDir_it)->path); free(*(ppDir_it++)); } free(local_files); n_local = 0; if ((local_dir_path = get_cwdir()) == NULL) { local_dir_path = malloc(2); strcpy(local_dir_path, "."); } adjust_path(fm->txt_local_dir, local_dir_path); if ((pDir = opendir(local_dir_path)) != NULL) while ((dir_ent = readdir(pDir))) { lstat(dir_ent->d_name, &stbuf); if (strcmp(dir_ent->d_name, ".") == 0 || strcmp(dir_ent->d_name, "..") == 0) continue; if (dir_ent->d_name[0] == '.' && !show_hidden_local) continue; add_file_to_list(&last_file, dir_ent->d_name, stbuf.st_size, stbuf.st_mtime, stbuf.st_mode, NULL); n_local++; } add_file_to_list(&last_file, "..", -1, -1, S_IFDIR, NULL); n_local++; local_files = put_files_into_array(last_file, n_local); put_files_into_browser(fm->br_local, fm->br_local_size, local_files, n_local, sort_key_local); free(local_dir_path); } struct dir_buf_item * read_rdir_to_mem(int rescan) { int i, bytes_received, iLink, found = 0, length; long size, mode; char c1, read_line[512], *pc1, *pc2, *bgn, *end, *pwd_reply, *rdp; struct dir_item *last_file = NULL, **ppFiles; struct dir_buf_item *pDbi = dir_buf; if (send_command("PWD", NULL, &pwd_reply) == 257) { bgn = strchr(pwd_reply, '"'); end = strrchr(pwd_reply, '"'); if (bgn != NULL && end != NULL && bgn != end) { i = end - bgn; rdp = malloc(i); strncpy(rdp, ++bgn, --i); rdp[i] = '\0'; } while (pDbi != NULL) { if (strcmp(pDbi->dir_path, rdp) == 0) { found = 1; break; } pDbi = pDbi->next; } if (found && !rescan) return pDbi; } else { rdp = malloc(2); strcpy(rdp, "."); } length = 0; if (cur_type != ASCII && send_command("TYPE A", NULL, NULL) == 200) cur_type = ASCII; if (data_command("LIST", NULL) != 150) goto read_err; while (1) { for (bytes_received = 0;; bytes_received++) { while ((i = read(sock_servDTP, &c1, 1)) < 0) { if (!con_opened) goto read_err; if (errno != EAGAIN) { add_to_log_err("read"); goto read_err; } fl_check_forms(); } if (c1 == '\n') break; read_line[bytes_received] = c1; } if (i == 0) break; if (read_line[bytes_received - 1] == '\r') bytes_received--; read_line[bytes_received] = '\0'; iLink = 1; if (strpbrk(read_line, "dlspbc-") != read_line) continue; switch (*read_line) { case 'l': iLink = 3; mode = S_IFLNK; break; case 'd': mode = S_IFDIR; break; default: if (read_line[3] == 'x') mode = S_IXUSR; else mode = 0; } pc1 = read_line; for (i = 0; i < 4; i++) { pc2 = pc1; while (*pc1 != ' ' && *pc1 != '\0') pc1++; while (*pc1 == ' ' && *pc1 != '\0') pc1++; } if (!isdigit(*pc1)) pc1 = pc2; size = atol(pc1); for (i = 0; i < 4; i++) { pc2 = pc1; while (*pc1 != ' ' && *pc1 != '\0') pc1++; while (*pc1 == ' ' && *pc1 != '\0') pc1++; } if (pc1[0] == '.' && !show_hidden_remote) continue; if (strcmp(pc1, ".") == 0 || strcmp(pc1, "..") == 0) continue; add_file_to_list(&last_file, pc1, size, 0, mode, NULL); length++; } add_file_to_list(&last_file, "..", -1, -1, S_IFDIR, NULL); length++; ppFiles = put_files_into_array(last_file, length); get_reply(NULL); if (found) { free(pDbi->dir); pDbi->dir_len = length; pDbi->dir = ppFiles; } else { pDbi = malloc(sizeof(struct dir_buf_item)); pDbi->dir_path = malloc(strlen(rdp) + 1); strcpy(pDbi->dir_path, rdp); pDbi->dir_len = length; pDbi->dir = ppFiles; pDbi->next = dir_buf; pDbi->top = 1; dir_buf = pDbi; } close(sock_servDTP); close(sock_userDTP); return pDbi; read_err: close(sock_servDTP); close(sock_userDTP); return NULL; } int read_remote_dir(int rescan) { struct dir_buf_item *pDbi; int i; fl_clear_browser(fm->br_remote); fl_clear_browser(fm->br_remote_size); if (cur_dir != NULL) { cur_dir->dir_len = n_remote; cur_dir->dir = remote_files; for (i = 0; i < n_remote; i++) remote_files[i]->selected = 0; } pDbi = read_rdir_to_mem(rescan); if (pDbi == NULL) return -1; free(remote_dir_path); remote_dir_path = malloc(strlen(pDbi->dir_path) + 1); strcpy(remote_dir_path, pDbi->dir_path); adjust_path(fm->txt_remote_dir, remote_dir_path); remote_files = pDbi->dir; n_remote = pDbi->dir_len; put_files_into_browser(fm->br_remote, fm->br_remote_size, remote_files, n_remote, sort_key_remote); fl_set_browser_topline(fm->br_remote, pDbi->top); fl_set_browser_topline(fm->br_remote_size, pDbi->top); cur_dir = pDbi; return 1; } void create_forms() { fm = create_form_fd_main(); fcp = create_form_fd_conn_par(); fb = create_form_fd_bookmarks(); fo = create_form_fd_options(); fon = create_form_fd_options_net(); fof = create_form_fd_options_fonts(); fofl = create_form_fd_options_files(); foc = create_form_fd_options_colors(); fa = create_form_fd_about(); fd = create_form_fd_download(); fdq = create_form_fd_download_question(); fi = create_form_fd_input(); fq = create_form_fd_question(); fmsg = create_form_fd_message(); frv = create_form_fd_remote_view(); flv = create_form_fd_local_view(); fc = create_form_fd_colors(); forms[0] = fm->fd_main; forms[1] = fcp->fd_conn_par; forms[2] = fo->fd_options; forms[3] = fon->fd_options_net; forms[4] = fof->fd_options_fonts; forms[5] = fa->fd_about; forms[6] = fd->fd_download; forms[7] = fdq->fd_download_question; forms[8] = fi->fd_input; forms[9] = fq->fd_question; forms[10] = fmsg->fd_message; forms[11] = frv->fd_remote_view; forms[12] = flv->fd_local_view; forms[13] = fofl->fd_options_files; forms[14] = fb->fd_bookmarks; forms[15] = foc->fd_options_colors; forms[16] = fc->fd_colors; } void change_font_s(int form_no) { FL_OBJECT *p1; double k; fl_freeze_form(forms[form_no]); p1 = forms[form_no]->first; while (1) { fl_set_object_lsize(p1, font_size); if (p1->objclass == FL_BROWSER) fl_set_browser_fontsize(p1, br_fsize); if (p1 == forms[form_no]->last) break; p1 = p1->next; } k = fl_adjust_form_size(forms[form_no]); if (form_no == 0) { minx = (double)minx * k; miny = (double)miny * k; fl_set_form_minsize(forms[form_no], minx, miny); } fl_set_form_size(forms[form_no], forms[form_no]->w + 1, forms[form_no]->h + 1); fl_unfreeze_form(forms[form_no]); } void change_font_size() { int i; for (i = 0; i < N_FORMS; i++) if (i != 2) /* without this exception aplication dumps core */ change_font_s (i); } void sort(struct dir_item **ppFiles, int iFiles, int sort_key) { if (sort_key == BY_NAME) qsort(ppFiles, iFiles, sizeof(struct dir_item *), cmp_name); else qsort(ppFiles, iFiles, sizeof(struct dir_item *), cmp_size); } int send_com_no_reply(const char *command, const char *arg, int flags, int crlf) { char line_to_send[strlen(command) + (arg != NULL ? strlen(arg) : 0) + 10]; if (crlf) { if (arg != NULL) sprintf(line_to_send, "%s %s\r\n", command, arg); else sprintf(line_to_send, "%s\r\n", command); } else sprintf(line_to_send, "%s", command); while (send(sock_servPI, line_to_send, strlen(line_to_send), flags) < 0) { if (!con_opened) return -1; if (errno != EWOULDBLOCK) { add_to_log_err("send"); return -1; } check_forms(); } if (crlf) { if (arg != NULL) { sprintf(line_to_send, "%s %s", command, (strncmp(command, "PASS", 4) || anonym_login) ? arg : "XXXX"); add_to_log(line_to_send); } else add_to_log(command); } return 0; } int send_command(const char *command, const char *arg, char **pReply) { if (send_com_no_reply(command, arg, 0, 1) < 0) return -1; return (get_reply(pReply)); } int get_reply(char **pReply) { char reply[256], rb[5], c1; int i = 1, j, multi = 0; while (1) { for (j = 0; i > 0; j++) { while ((i = read(sock_servPI, &c1, 1)) < 0) { if (!con_opened) return -1; if (errno != EAGAIN) { add_to_log_err("read"); return -1; } check_forms(); } if (c1 == '\n') break; reply[j] = c1; } if (i == 0) break; reply[j - 1] = '\0'; add_to_log(reply); if (pReply != NULL) { *pReply = malloc(strlen(reply) + 1); strcpy(*pReply, reply); } if (reply[3] == '-') { multi = 1; strncpy(rb, reply, 3); rb[3] = ' '; rb[4] = '\0'; } if (!multi || strncmp(reply, rb, 4) == 0) break; reply[3] = ' '; } return atoi(reply); } int open_ftp_connection() { struct hostent *h_ent = NULL; int i, on = 1; char *status; fl_set_object_label(fm->txt_status, "Looking up for host"); memset(&serverPI.sin_addr, 0, sizeof(serverPI.sin_addr)); serverPI.sin_port = htons(port); if ((h_ent = gethostbyname(address)) == NULL) { add_to_log_err("gethostbyname"); goto op_err; } serverPI.sin_family = h_ent->h_addrtype; serverPI.sin_addr = *((struct in_addr *) *(h_ent->h_addr_list)); if ((sock_servPI = socket(serverPI.sin_family, SOCK_STREAM, 0)) < 0) { add_to_log_err("socket"); goto op_err; } if (fcntl(sock_servPI, F_SETFL, O_NONBLOCK) < 0) { add_to_log_err("fcntl"); goto op_err; } status = malloc(strlen(address) + 15); sprintf(status, "Connecting to %s", address); fl_set_object_label(fm->txt_status, status); while (connect(sock_servPI, (struct sockaddr *) &serverPI, sizeof(serverPI)) < 0) { if (con_canceled) return -1; if (errno == EISCONN) break; if (errno == EINPROGRESS || errno == EAGAIN || errno == EALREADY) { check_forms(); continue; } if (*++h_ent->h_addr_list != NULL) serverPI.sin_addr = *((struct in_addr *) *(h_ent->h_addr_list)); else { add_to_log_err("connect"); goto op_err; } } i = sizeof(struct sockaddr_in); if (getsockname(sock_servPI, (struct sockaddr *) &userDTP, &i) < 0) { add_to_log_err("getsockname"); close(sock_servPI); goto op_err; } setsockopt(sock_servPI, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); return 1; op_err: fl_set_object_label(fm->txt_status, strerror(errno)); return -1; } int data_command2(const char *command1, const char *arg1, const char *command2, const char *arg2) { struct sockaddr_in serverDTP; char port_command[50]; char *a, *p, *pasv_reply = NULL, *pc1; int i, rp, ai[6]; unsigned char ac[6]; if ((sock_userDTP = socket(AF_INET, SOCK_STREAM, 0)) < 0) { add_to_log_err("socket"); return -1; } if (passive) { if (send_command("PASV", NULL, &pasv_reply) != 227) { free(pasv_reply); return -1; } pc1 = pasv_reply + 3; while (*pc1 != '\0' && !isdigit(*pc1)) pc1++; if (*pc1 == '\0') { free(pasv_reply); return -1; } sscanf(pc1, "%d,%d,%d,%d,%d,%d", &ai[0], &ai[1], &ai[2], &ai[3], &ai[4], &ai[5]); for (i = 0; i < 6; i++) ac[i] = (unsigned char) ai[i]; memcpy(&serverDTP.sin_addr, &ac[0], 4); memcpy(&serverDTP.sin_port, &ac[4], 2); serverDTP.sin_family = AF_INET; if ((sock_servDTP = socket(AF_INET, SOCK_STREAM, 0)) < 0) { add_to_log_err("socket"); return -1; } if (!ninteract) if (fcntl(sock_servDTP, F_SETFL, O_NONBLOCK) < 0) { add_to_log_err("fcntl"); return -1; } while (connect(sock_servDTP, (struct sockaddr *) &serverDTP, sizeof(serverDTP)) < 0) { if (!con_opened) return -1; if (errno == EISCONN) break; if (errno == EINPROGRESS || errno == EAGAIN || errno == EALREADY) { check_forms(); continue; } add_to_log_err("connect"); return -1; } free(pasv_reply); if (command1 != NULL && send_command(command1, arg1, NULL) >= 400) return -1; rp = send_command(command2, arg2, NULL); return rp; } else { if (!ninteract) if (fcntl(sock_userDTP, F_SETFL, O_NONBLOCK) < 0) { add_to_log_err("fcntl"); return -1; } userDTP.sin_port = 0; if (bind(sock_userDTP, (struct sockaddr *) &userDTP, sizeof(userDTP)) < 0) { add_to_log_err("bind"); return -1; } i = sizeof(struct sockaddr_in); if (getsockname(sock_userDTP, (struct sockaddr *) &userDTP, &i) < 0) { add_to_log_err("getsockname"); return -1; } if (listen(sock_userDTP, 5) < 0) { add_to_log_err("listen"); return -1; } a = (char *) &userDTP.sin_addr; p = (char *) &userDTP.sin_port; #define UC(x) (((int) x) & 0xff) sprintf(port_command, "PORT %d,%d,%d,%d,%d,%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); if (send_command(port_command, NULL, NULL) != 200) return -1; if (command1 != NULL && send_command(command1, arg1, NULL) >= 400) return -1; rp = send_command(command2, arg2, NULL); if (rp >= 300) return rp; i = sizeof(serverDTP); while ((sock_servDTP = accept(sock_userDTP, (struct sockaddr *) &serverDTP, &i)) < 0) { if (errno != EWOULDBLOCK) { add_to_log_err("accept"); return -1; } if (!con_opened) return -1; check_forms(); } return rp; } } int data_command(const char *command, const char *arg) { return data_command2(NULL, NULL, command, arg); } void download(struct dir_item **ppFiles_to_download, int n_files) { int mode, bytes_received, i, j, bytes_wrote, dest_file, action[n_files], flags; long bytes_transm, elapsed_time, estimated_time; float transfer_rate; char tmp_str[150], receive_buf[BUF_SIZE], *pc1, *pc2, *rfn, *lfn; char *cfile_name, *full_fname, *file_name; struct dir_item *pFile; struct stat stbuf; struct timeval start_time, cur_time; FL_OBJECT *ob; for (j = 0; j < n_files; j++) { if (S_ISLNK(ppFiles_to_download[j]->mode)) file_name = ppFiles_to_download[j]->link_name; else file_name = ppFiles_to_download[j]->file_name; if (lstat(file_name, &stbuf) == 0) { deactivate_form(fm->fd_main); if (stbuf.st_size < ppFiles_to_download[j]->file_size && type == BIN) sprintf(tmp_str, "Local file %s exists\nand is shorter than remote file!", cfile_name = cut(ppFiles_to_download[j]->file_name)); else { deactivate_object(fdq->resume_transf); sprintf(tmp_str, "Local file %s exists!", cfile_name = cut(file_name)); } free(cfile_name); fl_show_form(fdq->fd_download_question, FL_PLACE_MOUSE, FL_TRANSIENT, ""); fl_set_object_label(fdq->txt, tmp_str); ob = fl_do_forms(); if (ob == fdq->cancel) action[j] = CANCEL; if (ob == fdq->overwrite) action[j] = OVERWRITE; if (ob == fdq->resume_transf) action[j] = RESUME_TRANSF; if (fdq->resume_transf->active <= 0) activate_object(fdq->resume_transf); fl_hide_form(fdq->fd_download_question); activate_form(fm->fd_main); } else action[j] = OVERWRITE; } deactivate_form(fm->fd_main); fl_show_form(fd->fd_download, FL_PLACE_GEOMETRY, FL_TRANSIENT, "Xrmftp: download"); center_downl(); for (j = 0; j < n_files && !aborted; j++) { pFile = ppFiles_to_download[j]; if (S_ISLNK(pFile->mode)) file_name = pFile->link_name; else file_name = pFile->file_name; if (action[j] == CANCEL) continue; if ((pFile->mode & S_IXUSR) == S_IXUSR) mode = 0777; else mode = 0666; if (pFile->path != NULL) { full_fname = malloc(strlen(pFile->path) + strlen(file_name) + 4); sprintf(full_fname, "%s/%s", pFile->path, file_name); rfn = full_fname; } else { full_fname = NULL; rfn = file_name; } lfn = file_name; if (!ninteract) { if (action[j] == OVERWRITE) { flags = O_CREAT | O_WRONLY | O_TRUNC; fl_set_object_label(fmsg->txt, "Can not create file !"); } else { flags = O_APPEND | O_WRONLY; fl_set_object_label(fmsg->txt, "Can not open file !"); } fl_set_slider_bounds(fd->sl_time, 0, (double) (pFile->file_size)); fl_set_slider_value(fd->sl_time, 0); cfile_name = cut(rfn); fl_set_object_label(fd->txt_file_name, cfile_name); free(cfile_name); fl_set_object_label(fd->txt_transm, "0"); if (pFile->file_size < 1024) sprintf(tmp_str, "%li", pFile->file_size); else sprintf(tmp_str, "%li k", pFile->file_size >> 10); fl_set_object_label(fd->txt_total, tmp_str); fl_set_object_label(fd->txt_transfer_rate, ""); fl_set_object_label(fd->txt_elapsed_time, ""); fl_set_object_label(fd->txt_estimated_time, ""); fl_check_forms(); } if (type != cur_type && send_command("TYPE", type == ASCII ? "A" : "I", NULL) == 200) cur_type = type; if (action[j] == RESUME_TRANSF) { lstat(lfn, &stbuf); bytes_transm = stbuf.st_size; sprintf(tmp_str, "%li", stbuf.st_size); if (data_command2("REST", tmp_str, "RETR", rfn) != 150) goto download_err; } else { bytes_transm = 0; if (data_command("RETR", rfn) != 150) goto download_err; } if ((dest_file = open(lfn, flags, mode)) < 0) { if (!ninteract) { deactivate_form(fm->fd_main); fl_show_form(fmsg->fd_message, FL_PLACE_MOUSE, FL_TRANSIENT, ""); fl_do_forms(); fl_hide_form(fmsg->fd_message); activate_form(fm->fd_main); } return; } if (!ninteract) { } gettimeofday(&start_time, NULL); while (1) { while ((bytes_received = read(sock_servDTP, receive_buf, BUF_SIZE)) < 0) { if (errno != EAGAIN) { add_to_log_err("read"); goto download_err1; } check_forms(); if (aborted) goto download_err1; } if (bytes_received == 0) break; if (aborted) goto download_err1; pc1 = pc2 = receive_buf; bytes_wrote = bytes_received; if (type == ASCII) { bytes_wrote = 0; for (i = 0; i < bytes_received; i++) { if (*pc1 != '\r') { *(pc2++) = *pc1; bytes_wrote++; } pc1++; } } if (sys_unix) bytes_transm += bytes_wrote; else bytes_transm += bytes_received; check_forms(); write(dest_file, receive_buf, bytes_wrote); gettimeofday(&cur_time, NULL); elapsed_time = cur_time.tv_sec - start_time.tv_sec; if (!ninteract) { if (elapsed_time != 0) { transfer_rate = (float) bytes_transm / (float) elapsed_time; estimated_time = pFile->file_size / transfer_rate; sprintf(tmp_str, "%.2f kbytes/sec.", transfer_rate / 1024); fl_set_object_label(fd->txt_transfer_rate, tmp_str); sprintf(tmp_str, "%li sec.", elapsed_time); fl_set_object_label(fd->txt_elapsed_time, tmp_str); sprintf(tmp_str, "%li sec.", estimated_time); fl_set_object_label(fd->txt_estimated_time, tmp_str); } if (bytes_transm < 1024) sprintf(tmp_str, "%li", bytes_transm); else sprintf(tmp_str, "%li k", bytes_transm >> 10); fl_set_object_label(fd->txt_transm, tmp_str); fl_set_slider_value(fd->sl_time, bytes_transm); } } download_err1: close(sock_servDTP); close(sock_userDTP); if (aborted) get_reply(NULL); get_reply(NULL); download_err: close(dest_file); free(full_fname); } if (aborted) aborted = 0; if (ninteract) { if (flog != NULL) fclose(flog); exit(0); } else { fl_hide_form(fd->fd_download); activate_form(fm->fd_main); } } void upload(struct dir_item **ppFiles_to_upload, int n_files, int recurs) { int bytes_read, i, j, bytes_to_sent, bytes_sent, bs, src_file, action[n_files], fexists; long bytes_transm, elapsed_time, estimated_time; double transfer_rate; char tmp_str[150], send_buf[2 * BUF_SIZE], read_buf[BUF_SIZE], *pc1, *pc2, *rfn, *lfn; char *cfile_name, *file_name; struct dir_item *pFile, *pDest_file; struct timeval start_time, cur_time; FL_OBJECT *ob; for (j = 0; j < n_files; j++) { file_name = ppFiles_to_upload[j]->file_name; fexists = 0; if (!recurs) { for (i = 0; i < n_remote; i++) if (strcmp(file_name, remote_files[i]->file_name) == 0) { fexists = 1; pDest_file = remote_files[i]; break; } } if (fexists) { deactivate_form(fm->fd_main); if (pDest_file->file_size < ppFiles_to_upload[j]->file_size && type == BIN) sprintf(tmp_str, "Remote file %s exists\nand is shorter than local file!", cfile_name = cut(ppFiles_to_upload[j]->file_name)); else { deactivate_object(fdq->resume_transf); sprintf(tmp_str, "Remote file %s exists!", cfile_name = cut(file_name)); } free(cfile_name); fl_show_form(fdq->fd_download_question, FL_PLACE_MOUSE, FL_TRANSIENT, ""); fl_set_object_label(fdq->txt, tmp_str); ob = fl_do_forms(); if (ob == fdq->cancel) action[j] = CANCEL; if (ob == fdq->overwrite) action[j] = OVERWRITE; if (ob == fdq->resume_transf) action[j] = RESUME_TRANSF; if (fdq->resume_transf->active <= 0) activate_object(fdq->resume_transf); fl_hide_form(fdq->fd_download_question); activate_form(fm->fd_main); } else action[j] = OVERWRITE; } for (j = 0; j < n_files && !aborted; j++) { pFile = ppFiles_to_upload[j]; file_name = pFile->file_name; if (action[j] == CANCEL) continue; lfn = file_name; rfn = file_name; if ((src_file = open(lfn, O_RDONLY)) < 0) { if (!ninteract) { deactivate_form(fm->fd_main); fl_set_object_label(fmsg->txt, "Can not open file !"); fl_show_form(fmsg->fd_message, FL_PLACE_MOUSE, FL_TRANSIENT, ""); fl_do_forms(); fl_hide_form(fmsg->fd_message); activate_form(fm->fd_main); } return; } deactivate_form(fm->fd_main); if (type != cur_type && send_command("TYPE", type == ASCII ? "A" : "I", NULL) == 200) cur_type = type; if (action[j] == RESUME_TRANSF) { bytes_transm = pDest_file->file_size; if (data_command("APPE", rfn) != 150) goto upload_err; } else { bytes_transm = 0; if (data_command("STOR", rfn) != 150) goto upload_err; } if (!ninteract) { fl_set_slider_bounds(fd->sl_time, 0, (double) (pFile->file_size)); fl_set_slider_value(fd->sl_time, bytes_transm); cfile_name = cut(rfn); fl_set_object_label(fd->txt_file_name, cfile_name); free(cfile_name); fl_set_object_label(fd->txt_transm, "0"); if (pFile->file_size < 1024) sprintf(tmp_str, "%li", pFile->file_size); else sprintf(tmp_str, "%li k", pFile->file_size >> 10); fl_set_object_label(fd->txt_total, tmp_str); center_downl(); fl_show_form(fd->fd_download, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); fl_check_forms(); } lseek(src_file, bytes_transm, SEEK_SET); gettimeofday(&start_time, NULL); while (1) { bytes_read = read(src_file, read_buf, BUF_SIZE); if (bytes_read == 0) break; pc1 = read_buf; pc2 = send_buf; bytes_to_sent = bytes_read; if (type == ASCII) { bytes_to_sent = 0; for (i = 0; i < bytes_read; i++) { if (*pc1 == '\n') { *(pc2++) = '\r'; bytes_to_sent++; } *(pc2++) = *(pc1++); bytes_to_sent++; } pc2 = send_buf; } else pc2 = read_buf; if (aborted) break; bytes_sent = 0; while ((bs = write(sock_servDTP, pc2 + bytes_sent, bytes_to_sent - bytes_sent)) < 0 || bytes_sent < bytes_to_sent) { if (bs > 0) bytes_sent += bs; if (errno != EAGAIN && errno !=0) { add_to_log_err("write"); perror("write"); printf("E %d %d %d\n", errno, bytes_sent, bytes_to_sent); goto upload_err1; } check_forms(); } if (sys_unix) bytes_transm += bytes_sent; else bytes_transm += bytes_read; check_forms(); gettimeofday(&cur_time, NULL); elapsed_time = cur_time.tv_sec - start_time.tv_sec; if (!ninteract) { if (elapsed_time != 0) { transfer_rate = (float) bytes_transm / (float) elapsed_time; estimated_time = pFile->file_size / transfer_rate; sprintf(tmp_str, "%.2f kbytes/sec.", transfer_rate / 1024); fl_set_object_label(fd->txt_transfer_rate, tmp_str); sprintf(tmp_str, "%li", elapsed_time); fl_set_object_label(fd->txt_elapsed_time, tmp_str); sprintf(tmp_str, "%li", estimated_time); fl_set_object_label(fd->txt_estimated_time, tmp_str); } if (bytes_transm < 1024) sprintf(tmp_str, "%li", bytes_transm); else sprintf(tmp_str, "%li k", bytes_transm >> 10); fl_set_object_label(fd->txt_transm, tmp_str); fl_set_slider_value(fd->sl_time, bytes_transm); } } upload_err1: close(sock_servDTP); close(sock_userDTP); if (aborted) get_reply(NULL); get_reply(NULL); if (!ninteract) fl_hide_form(fd->fd_download); upload_err: close(src_file); activate_form(fm->fd_main); } if (aborted) aborted = 0; if (ninteract) { if (flog != NULL) fclose(flog); exit(0); } } /* fd_main callbacks : */ void cb_close(FL_OBJECT * ob, long arg) { int i; struct dir_item **ppDir_it; struct dir_buf_item *pDbi; con_canceled = 1; if (!con_opened) { con_opened = 0; return; } send_com_no_reply("QUIT", NULL, 0, 1); fl_set_form_title(fm->fd_main, "Xrmftp"); close(sock_servPI); add_to_history(); if (cur_dir != NULL) { cur_dir->dir_len = n_remote; cur_dir->dir = remote_files; } while (dir_buf != NULL) { ppDir_it = dir_buf->dir; for (i = 0; i < dir_buf->dir_len; i++) { free((*ppDir_it)->file_name); free((*ppDir_it)->link_name); free((*ppDir_it)->path); free(*(ppDir_it++)); } free(dir_buf->dir); free(dir_buf->dir_path); pDbi = dir_buf; dir_buf = dir_buf->next; free(pDbi); } cur_dir = NULL; fl_clear_browser(fm->br_remote); fl_clear_browser(fm->br_remote_size); fl_set_object_label(fm->txt_remote_dir, ""); deactivate_object(fm->remote_btns); deactivate_object(fm->br_remote); deactivate_object(fm->br_remote_size); fl_set_object_label(fm->con_close, "Connect"); fl_set_object_callback(fm->con_close, cb_connect, 0); con_opened = 0; } void cb_connect(FL_OBJECT * ob, long arg) { int x, y; if (fcp->br_history->visible) cb_history(ob, 0); x = fm->fd_main->x + (fm->fd_main->w - fcp->fd_conn_par->w) / 2; y = fm->fd_main->y + (fm->fd_main->h - fcp->fd_conn_par->h) / 2; fl_set_form_position(fcp->fd_conn_par, x, y); fl_show_form(fcp->fd_conn_par, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); deactivate_form(fm->fd_main); fl_set_focus_object(fcp->fd_conn_par, fcp->address); } void cb_about(FL_OBJECT * ob, long arg) { deactivate_form(fm->fd_main); fl_show_form(fa->fd_about, FL_PLACE_MOUSE, FL_TRANSIENT, ""); } void cb_exit(FL_OBJECT * ob, long arg) { struct hist_item *pHist_it; if (con_opened) { send_com_no_reply("QUIT", NULL, 0, 1); add_to_history(); close(sock_servPI); } fl_finish(); while (hist_first != NULL) { free(hist_first->address); free(hist_first->user_name); free(hist_first->pass_unenc); free(hist_first->local_dir); free(hist_first->remote_dir); pHist_it = hist_first->next; free(hist_first); hist_first = pHist_it; } free(home_dir); free(opt_file_name); free(hist_file_name); free(log_file_name); free(address); free(user_name); free(pass_enc); free(pass_unenc); free(local_dir_path_inp); free(remote_dir_path_inp); if (flog != NULL) fclose(flog); exit(0); } void cb_type(FL_OBJECT * ob, long arg) { if (ob == fm->binary) type = BIN; else type = ASCII; } void clear_buffer() { struct dir_item *pDir_it = buffer_list; while (buffer_list != NULL) { pDir_it = buffer_list->next; free(buffer_list); buffer_list = pDir_it; } fl_clear_browser(fm->br_buffer_name); fl_set_object_label(fm->txt_buffer, ""); n_buffer = 0; } void download_dir(const char *dir, const char *old_dir, const char *old_ldir) { struct dir_item **ppFiles_to_download, **ppFiles; struct dir_buf_item *pDbi; int i, j = 0; char *crd; send_command("CWD", dir, NULL); if ((pDbi = read_rdir_to_mem(0)) == NULL) { send_command("CWD", old_dir, NULL); return; } if (mkdir(dir, 0777) < 0 || chdir(dir) < 0) { send_command("CWD", old_dir, NULL); return; } crd = get_cwdir(); ppFiles = pDbi->dir; ppFiles_to_download = malloc(pDbi->dir_len * sizeof(struct dir_item *)); for (i = 0; i < pDbi->dir_len; i++) if (!S_ISDIR(ppFiles[i]->mode)) ppFiles_to_download[j++] = ppFiles[i]; if (j) download(ppFiles_to_download, j); free(ppFiles_to_download); for (i = 0; i < pDbi->dir_len; i++) { if (S_ISDIR(ppFiles[i]->mode) && strcmp(ppFiles[i]->file_name, "..")) download_dir(ppFiles[i]->file_name, pDbi->dir_path, crd); } free(crd); chdir(old_ldir); send_command("CWD", old_dir, NULL); } void cb_download_buffer(FL_OBJECT * ob, long arg) { int i, j = 0; struct dir_item *apFiles_to_download[n_buffer], *pDir_it = buffer_list; char *crd = get_cwdir(); for (i = 0; i < n_buffer; i++) { if (!S_ISDIR(pDir_it->mode)) apFiles_to_download[j++] = pDir_it; pDir_it = pDir_it->next; } if (j) download(apFiles_to_download, j); pDir_it = buffer_list; for (i = 0; i < n_buffer; i++) { if (S_ISDIR(pDir_it->mode) && strcmp(pDir_it->file_name, "..")) { send_command("CWD", pDir_it->path, NULL); download_dir(pDir_it->file_name, pDir_it->path, crd); send_command("CWD", remote_dir_path, NULL); } pDir_it = pDir_it->next; } free(crd); clear_buffer(); read_local_dir(); } void rem_from_buf(int line) { int i; struct dir_item *pDir_it = buffer_list, *pDir_it1; fl_delete_browser_line(fm->br_buffer_name, line); if (line == n_buffer) { buffer_list = buffer_list->next; free(pDir_it->file_name); free(pDir_it->link_name); free(pDir_it->path); free(pDir_it); n_buffer--; return; } for (i = n_buffer; i > line + 1; i--) pDir_it = pDir_it->next; pDir_it1 = pDir_it->next; pDir_it->next = pDir_it1->next; free(pDir_it1->file_name); free(pDir_it->link_name); free(pDir_it1->path); free(pDir_it1); n_buffer--; } void cb_rem_from_buf(FL_OBJECT * ob, long arg) { int i; fl_freeze_form(fm->fd_main); for (i = n_buffer; i > 0; i--) if (fl_isselected_browser_line(fm->br_buffer_name, i)) rem_from_buf(i); fl_set_object_label(fm->txt_buffer, ""); fl_unfreeze_form(fm->fd_main); } void cb_br_local(FL_OBJECT * ob, long arg) { int i = fl_get_browser(ob); if (i > 0) { local_files[i - 1]->selected = 1; if (ob == fm->br_local) fl_select_browser_line(fm->br_local_size, i); else fl_select_browser_line(fm->br_local, i); return; } if (i < 0) { local_files[-i - 1]->selected = 0; if (ob == fm->br_local) fl_deselect_browser_line(fm->br_local_size, -i); else fl_deselect_browser_line(fm->br_local, -i); } } void cb_br_remote(FL_OBJECT * ob, long arg) { int i = fl_get_browser(ob); if (i > 0) { remote_files[i - 1]->selected = 1; if (ob == fm->br_remote) fl_select_browser_line(fm->br_remote_size, i); else fl_select_browser_line(fm->br_remote, i); return; } if (i < 0) { remote_files[-i - 1]->selected = 0; if (ob == fm->br_remote) fl_deselect_browser_line(fm->br_remote_size, -i); else fl_deselect_browser_line(fm->br_remote, -i); } } void cb_br_buffer(FL_OBJECT * ob, long arg) { int i = fl_get_browser(ob), j; struct dir_item *pDir_it = buffer_list; if (i > 0) { for (j = i; j < n_buffer; j++) pDir_it = pDir_it->next; adjust_path(fm->txt_buffer, pDir_it->path); } else fl_set_object_label(fm->txt_buffer, ""); } void cb2_br_local(FL_OBJECT * ob, long arg) { int line; struct dir_item *pDir_it; if (fl_get_browser_maxline(ob) == 0) return; line = abs(fl_get_browser(ob)); pDir_it = local_files[line - 1]; if (S_ISDIR(pDir_it->mode) || S_ISLNK(pDir_it->mode)) { if (chdir(pDir_it->file_name) == 0) read_local_dir(); } } void cb_updir_local(FL_OBJECT * ob, long arg) { if (arg) { if (chdir("/") == 0) read_local_dir(); return; } if (chdir("..") == 0) read_local_dir(); } void cb_updir_remote(FL_OBJECT * ob, long arg) { if (arg) { if (send_command("CWD", "/", NULL) == 250) read_remote_dir(0); return; } if (send_command("CWD", "..", NULL) == 250) read_remote_dir(0); } void cb2_br_remote(FL_OBJECT * ob, long arg) { int line; struct dir_item *pDir_it; cur_dir->top = fl_get_browser_topline(fm->br_remote); if (fl_get_browser_maxline(ob) == 0) return; line = abs(fl_get_browser(ob)); pDir_it = remote_files[line - 1]; if (S_ISDIR(pDir_it->mode)) { deactivate_object(fm->remote_btns); deactivate_object(fm->br_remote); deactivate_object(fm->br_remote_size); if (send_command("CWD", pDir_it->file_name, NULL) == 250) read_remote_dir(0); activate_object(fm->remote_btns); activate_object(fm->br_remote); activate_object(fm->br_remote_size); } if (S_ISLNK(pDir_it->mode)) { deactivate_object(fm->remote_btns); deactivate_object(fm->br_remote); deactivate_object(fm->br_remote_size); if (send_command("CWD", pDir_it->link_name, NULL) == 250) read_remote_dir(0); activate_object(fm->remote_btns); activate_object(fm->br_remote); activate_object(fm->br_remote_size); } } void upload_dir(const char *dir) { struct dir_item *pFile_to_upload = malloc(sizeof(struct dir_item)); struct dirent *dir_ent; struct stat stbuf; DIR *pDir; if (chdir(dir) < 0) return; if (send_command("MKD", dir, NULL) != 257) { chdir(".."); return; } if (send_command("CWD", dir, NULL) != 250) { chdir(".."); return; } if ((pDir = opendir(".")) == NULL) { chdir(".."); send_command("CWD", "..", NULL); return; } while ((dir_ent = readdir(pDir))) { lstat(dir_ent->d_name, &stbuf); if (strcmp(dir_ent->d_name, ".") == 0 || strcmp(dir_ent->d_name, "..") == 0) continue; if (dir_ent->d_name[0] == '.' && !show_hidden_local) continue; if (!S_ISDIR(stbuf.st_mode)) { pFile_to_upload->file_name = dir_ent->d_name; pFile_to_upload->file_size = stbuf.st_size; pFile_to_upload->mode = stbuf.st_mode; upload(&pFile_to_upload, 1, 1); } else upload_dir(dir_ent->d_name); } chdir(".."); read_rdir_to_mem(0); send_command("CWD", "..", NULL); free(pFile_to_upload); } void cb_upload(FL_OBJECT * ob, long arg) { int i, j = 0; struct dir_item *apFiles_to_upload[n_local]; for (i = 1; i <= n_local; i++) if (fl_isselected_browser_line(fm->br_local, i) && !S_ISDIR(local_files[i - 1]->mode)) apFiles_to_upload[j++] = local_files[i - 1]; if (j) upload(apFiles_to_upload, j, 0); for (i = 1; i <= n_local; i++) if (fl_isselected_browser_line(fm->br_local, i) && S_ISDIR(local_files[i - 1]->mode) && strcmp(local_files[i - 1]->file_name, "..")) upload_dir(local_files[i - 1]->file_name); fl_deselect_browser(fm->br_local); fl_deselect_browser(fm->br_local_size); read_remote_dir(1); } void cb_download(FL_OBJECT * ob, long arg) { int i, j = 0; struct dir_item *apFiles_to_download[n_remote]; char *crd = get_cwdir(); for (i = 1; i <= n_remote; i++) if (fl_isselected_browser_line(fm->br_remote, i) && !S_ISDIR(remote_files[i - 1]->mode)) apFiles_to_download[j++] = remote_files[i - 1]; if (j) download(apFiles_to_download, j); for (i = 1; i <= n_remote; i++) if (fl_isselected_browser_line(fm->br_remote, i)) { if (S_ISDIR(remote_files[i - 1]->mode) && strcmp(remote_files[i - 1]->file_name, "..")) download_dir(remote_files[i - 1]->file_name, remote_dir_path, crd); } fl_deselect_browser(fm->br_remote); fl_deselect_browser(fm->br_remote_size); read_local_dir(); } void cb_to_buffer(FL_OBJECT * ob, long arg) { int n_lines, i, repeated; struct dir_item *pDir_it; n_lines = fl_get_browser_maxline(fm->br_remote); for (i = 2; i <= n_lines; i++) if (fl_isselected_browser_line(fm->br_remote, i)) { repeated = 0; pDir_it = buffer_list; while (pDir_it != NULL) { if (strcmp(remote_files[i - 1]->file_name, pDir_it->file_name) == 0) { repeated = 1; break; } pDir_it = pDir_it->next; } if (!repeated) { add_file_to_list(&buffer_list, remote_files[i - 1]->file_name, remote_files[i - 1]->file_size, remote_files[i - 1]->modif_time, remote_files[i - 1]->mode, remote_dir_path); fl_add_browser_line(fm->br_buffer_name, fl_get_browser_line(fm->br_remote, i)); n_buffer++; } } fl_deselect_browser(fm->br_remote); fl_deselect_browser(fm->br_remote_size); } int rmdir_rec(const char *dir_name) { struct stat stbuf; DIR *pDir; struct dirent *dir_ent; char *old_dir; if ((old_dir = get_cwdir()) == NULL) { free(old_dir); return -1; } chdir(dir_name); if ((pDir = opendir(".")) == NULL) { return -1; free(old_dir); } while ((dir_ent = readdir(pDir))) { lstat(dir_ent->d_name, &stbuf); if (strcmp(dir_ent->d_name, ".") == 0 || strcmp(dir_ent->d_name, "..") == 0) continue; if (S_ISDIR(stbuf.st_mode)) { if (rmdir(dir_ent->d_name) < 0 && (errno == ENOTEMPTY || errno == EEXIST)) rmdir_rec(dir_ent->d_name); } else remove(dir_ent->d_name); } chdir(old_dir); free(old_dir); return rmdir(dir_name); } void remove_dirs(int *selected, int n_sel, struct dir_item ***pppFiles, int *pn_files, int place) { int i, success; char label[150], *file_name, *cfile_name; if (n_sel == 1) { file_name = (*pppFiles)[selected[0]]->file_name; sprintf(label, "Remove directory %s ?", cfile_name = cut(file_name)); free(cfile_name); } else sprintf(label, "Remove %d directories ?", n_sel); fl_set_object_label(fq->txt_question, label); deactivate_form(fm->fd_main); fl_show_form(fq->fd_question, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); if (fl_do_forms() == fq->yes) for (i = n_sel; i > 0;) { success = 0; i--; file_name = (*pppFiles)[selected[i]]->file_name; if (place == LOCAL) { if (rmdir(file_name) == 0) success = 1; else if (errno == ENOTEMPTY || errno == EEXIST) { sprintf(label, "Directory %s is not empty.\nDelete it recursively ?", cfile_name = cut(file_name)); free(cfile_name); fl_set_object_label(fq->txt_question, label); if (fl_do_forms() == fq->yes) if (rmdir_rec(file_name) == 0); success = 1; } } else if (send_command("RMD", file_name, NULL) == 250) success = 1; if (success) remove_file_from_array(pppFiles, pn_files, selected[i]); } activate_form(fm->fd_main); fl_hide_form(fq->fd_question); } void remove_files(int *selected, int n_sel, struct dir_item ***pppFiles, int *pn_files, int place) { int i, success; char label[50], *file_name, *cfile_name; if (n_sel == 1) { file_name = (*pppFiles)[selected[0]]->file_name; sprintf(label, "Remove file %s ?", cfile_name = cut(file_name)); free(cfile_name); } else sprintf(label, "Remove %d files ?", n_sel); fl_set_object_label(fq->txt_question, label); deactivate_form(fm->fd_main); fl_show_form(fq->fd_question, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); if (fl_do_forms() == fq->yes) for (i = n_sel; i > 0;) { success = 0; i--; if (place == REMOTE && S_ISLNK((*pppFiles)[selected[i]]->mode)) file_name = (*pppFiles)[selected[i]]->link_name; else file_name = (*pppFiles)[selected[i]]->file_name; if (place == LOCAL) { if (remove(file_name) == 0) success = 1; } else if (send_command("DELE", file_name, NULL) == 250) success = 1; if (success) remove_file_from_array(pppFiles, pn_files, selected[i]); } activate_form(fm->fd_main); fl_hide_form(fq->fd_question); } void rename_files(int *selected, int n_sel, struct dir_item **ppFiles, int place) { int i, success; const char *new_name; char label[50], *cfile_name, *file_name; FL_OBJECT *ret_object; for (i = 0; i < n_sel; i++) { if (place == REMOTE && S_ISLNK(ppFiles[selected[i]]->mode)) file_name = ppFiles[selected[i]]->link_name; else file_name = ppFiles[selected[i]]->file_name; fl_set_input(fi->input, ""); sprintf(label, "Rename/move file %s to", cfile_name = cut(file_name)); fl_set_object_label(fi->txt_input, label); free(cfile_name); deactivate_form(fm->fd_main); fl_show_form(fi->fd_input, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); ret_object = fl_do_forms(); success = 0; if ((ret_object == fi->ok || ret_object == fi->input) && *(new_name = fl_get_input(fi->input)) != '\0') if (place == LOCAL) { if (rename(file_name, new_name) == 0) success = 1; } else if (send_command("RNFR", file_name, NULL) == 350 && send_command("RNTO", new_name, NULL) == 250) success = 1; if (success) { free(file_name); file_name = malloc(strlen(new_name) + 1); strcpy(file_name, new_name); ppFiles[selected[i]]->file_name = file_name; } fl_hide_form(fi->fd_input); activate_form(fm->fd_main); if (ret_object == fi->cancel) break; } } void cb_btn_local(FL_OBJECT * ob, long arg) { int n_sel = 0, x, y, i, *selected; const char *dir; char *cfile_name, *file_name, *cdir; FL_OBJECT *ret_ob; fl_set_input(fi->input, ""); x = fm->fd_main->x + 5; y = fm->fd_main->y + fm->br_local->y + fm->br_local->h + 4; fl_set_form_position(fq->fd_question, x, y); fl_set_form_position(fi->fd_input, x, y); if (arg < 3) { if (arg == 2) { fl_set_input(fi->input, cdir = get_cwdir()); fl_set_input_selected(fi->input, 1); free(cdir); } fl_set_object_label(fi->txt_input, "Enter directory name:"); fl_show_form(fi->fd_input, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); deactivate_form(fm->fd_main); ret_ob = fl_do_forms(); activate_form(fm->fd_main); fl_hide_form(fi->fd_input); if (ret_ob == fi->cancel) return; dir = fl_get_input(fi->input); } switch (arg) { case 1: if (mkdir(dir, 0777) == 0) { add_file_to_array(&local_files, &n_local, dir, 0, 0, S_IFDIR); put_files_into_browser(fm->br_local, fm->br_local_size, local_files, n_local, sort_key_local); } break; case 2: if (chdir(dir) == 0) read_local_dir(); break; case 3: selected = malloc(n_local * sizeof(int)); for (i = 1; i <= n_local; i++) if (fl_isselected_browser_line(fm->br_local, i)) selected[n_sel++] = i - 1; if (n_sel) { rename_files(selected, n_sel, local_files, LOCAL); put_files_into_browser(fm->br_local, fm->br_local_size, local_files, n_local, sort_key_local); } free(selected); break; case 4: selected = malloc(n_local * sizeof(int)); for (i = 1; i <= n_local; i++) if (fl_isselected_browser_line(fm->br_local, i) && S_ISDIR(local_files[i - 1]->mode)) selected[n_sel++] = i - 1; if (n_sel) { remove_dirs(selected, n_sel, &local_files, &n_local, LOCAL); put_files_into_browser(fm->br_local, fm->br_local_size, local_files, n_local, sort_key_local); } free(selected); break; case 5: selected = malloc(n_local * sizeof(int)); for (i = 1; i <= n_local; i++) if (fl_isselected_browser_line(fm->br_local, i) && !S_ISDIR(local_files[i - 1]->mode)) selected[n_sel++] = i - 1; if (n_sel) { remove_files(selected, n_sel, &local_files, &n_local, LOCAL); put_files_into_browser(fm->br_local, fm->br_local_size, local_files, n_local, sort_key_local); } free(selected); break; case 6: fl_clear_browser(flv->br_view); for (i = 1; i <= n_local; i++) if (fl_isselected_browser_line(fm->br_local, i)) { file_name = local_files[i - 1]->file_name; fl_set_object_label(flv->txt_file_name, cfile_name = cut(file_name)); free(cfile_name); fl_load_browser(flv->br_view, file_name); fl_show_form(flv->fd_local_view, FL_PLACE_MOUSE, FL_TRANSIENT, ""); break; } break; case 7: read_local_dir(); } } void cb_btn_remote(FL_OBJECT * ob, long arg) { int n_lines, x, y, i, *selected, n_sel = 0; const char *dir; FL_OBJECT *ret_ob; n_lines = fl_get_browser_maxline(fm->br_remote); fl_set_input(fi->input, ""); x = fm->fd_main->x + fm->txt_remote_dir->x + (fm->txt_remote_dir->w + -fq->fd_question->w) / 2; y = fm->fd_main->y + fm->br_remote->y + fm->br_remote->h + 4; fl_set_form_position(fq->fd_question, x, y); x = fm->fd_main->x + fm->txt_remote_dir->x + (fm->txt_remote_dir->w + -fi->fd_input->w) / 2; y = fm->fd_main->y + fm->br_remote->y + fm->br_remote->h + 4; fl_set_form_position(fi->fd_input, x, y); if (arg < 3) { if (arg == 2) { fl_set_input(fi->input, remote_dir_path); fl_set_input_selected(fi->input, 1); } fl_set_object_label(fi->txt_input, "Enter directory name:"); fl_show_form(fi->fd_input, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); deactivate_form(fm->fd_main); ret_ob = fl_do_forms(); activate_form(fm->fd_main); fl_hide_form(fi->fd_input); if (ret_ob == fi->cancel) return; dir = fl_get_input(fi->input); } deactivate_object(fm->remote_btns); deactivate_object(fm->br_remote); deactivate_object(fm->br_remote_size); switch (arg) { case 1: if (send_command("MKD", dir, NULL) == 257) { add_file_to_array(&remote_files, &n_remote, dir, 0, 0, S_IFDIR); put_files_into_browser(fm->br_remote, fm->br_remote_size, remote_files, n_remote, sort_key_remote); } break; case 2: if (send_command("CWD", dir, NULL) == 250) read_remote_dir(0); break; case 3: selected = malloc(n_remote * sizeof(int)); for (i = 1; i <= n_remote; i++) if (fl_isselected_browser_line(fm->br_remote, i)) selected[n_sel++] = i - 1; if (n_sel) { rename_files(selected, n_sel, remote_files, REMOTE); put_files_into_browser(fm->br_remote, fm->br_remote_size, remote_files, n_remote, sort_key_remote); } free(selected); break; case 4: selected = malloc(n_remote * sizeof(int)); for (i = 1; i <= n_remote; i++) if (fl_isselected_browser_line(fm->br_remote, i) && S_ISDIR(remote_files[i - 1]->mode)) selected[n_sel++] = i - 1; if (n_sel) { remove_dirs(selected, n_sel, &remote_files, &n_remote, REMOTE); put_files_into_browser(fm->br_remote, fm->br_remote_size, remote_files, n_remote, sort_key_remote); } free(selected); break; case 5: selected = malloc(n_remote * sizeof(int)); for (i = 1; i <= n_remote; i++) if (fl_isselected_browser_line(fm->br_remote, i) && !S_ISDIR(remote_files[i - 1]->mode)) selected[n_sel++] = i - 1; if (n_sel) { remove_files(selected, n_sel, &remote_files, &n_remote, REMOTE); put_files_into_browser(fm->br_remote, fm->br_remote_size, remote_files, n_remote, sort_key_remote); } free(selected); break; case 7: read_remote_dir(1); break; } activate_object(fm->remote_btns); activate_object(fm->br_remote); activate_object(fm->br_remote_size); } void cb_sort(FL_OBJECT * ob, long arg) { if (arg < 3) { sort_key_local = arg; put_files_into_browser(fm->br_local, fm->br_local_size, local_files, n_local, arg); } else { sort_key_remote = arg - 2; put_files_into_browser(fm->br_remote, fm->br_remote_size, remote_files, n_remote, arg - 2); } } void cb_remote_view(FL_OBJECT * ob, long arg) { int bytes_received, bytes_wrote, i; long bytes_transm, file_size; char *pc1, *pc2, fsize[25], receive_buf[BUF_SIZE + 1], *file_name, *cfile_name; for (i = 1; !fl_isselected_browser_line(fm->br_remote, i) || S_ISDIR(remote_files[i - 1]->mode); i++) if (i > n_remote) return; fl_clear_browser(frv->br_view); fl_set_object_label(frv->btn_ok_cnc, "Cancel"); fl_set_object_callback(frv->btn_ok_cnc, cb_dwnld_cancel, 0); if (S_ISLNK(remote_files[i - 1]->mode)) file_name = remote_files[i - 1]->link_name; else file_name = remote_files[i - 1]->file_name; file_size = remote_files[i - 1]->file_size; fl_set_object_label(frv->txt_transm, "0"); if (file_size < 1024) sprintf(fsize, "%li", file_size); else sprintf(fsize, "%li k", file_size >> 10); fl_set_object_label(frv->txt_total, fsize); fl_set_object_color(frv->sl_time, FL_COL1, FL_GREEN); fl_set_slider_bounds(frv->sl_time, 0, (double) (file_size)); fl_set_slider_value(frv->sl_time, 0); fl_set_object_label(frv->txt_file_name, cfile_name = cut(file_name)); free(cfile_name); busy = 1; deactivate_object(fm->local_btns); deactivate_object(fm->remote_btns); deactivate_object(fm->br_remote); deactivate_object(fm->br_remote_size); if (cur_type != ASCII && send_command("TYPE", "A", NULL) == 200) cur_type = ASCII; if (data_command("RETR", file_name) != 150) { activate_form(fm->fd_main); goto view_err; } deactivate_form(fm->fd_main); fl_show_form(frv->fd_remote_view, FL_PLACE_MOUSE, FL_TRANSIENT, ""); fl_check_forms(); bytes_transm = 0; while (1) { while ((bytes_received = read(sock_servDTP, receive_buf, BUF_SIZE)) < 0) { if (errno != EAGAIN) { add_to_log_err("read"); goto view_err1; } fl_check_forms(); if (aborted) goto view_err1; } if (bytes_received == 0) break; if (aborted) goto view_err1; pc1 = pc2 = receive_buf; bytes_wrote = 0; for (i = 0; i < bytes_received; i++) { if (*pc1 != '\r') { *(pc2++) = *pc1; bytes_wrote++; } pc1++; } receive_buf[bytes_wrote] = '\0'; if (sys_unix) bytes_transm += bytes_wrote; else bytes_transm += bytes_received; fl_check_forms(); for (i = 0; receive_buf[i] != '\n'; i++); receive_buf[i] = '\0'; fl_addto_browser_chars(frv->br_view, receive_buf); fl_add_browser_line(frv->br_view, receive_buf + i + 1); if (bytes_transm < 1024) sprintf(fsize, "%li", bytes_transm); else sprintf(fsize, "%li k", bytes_transm >> 10); fl_set_object_label(frv->txt_transm, fsize); fl_set_slider_value(frv->sl_time, bytes_transm); } view_err1: close(sock_servDTP); close(sock_userDTP); if (aborted) get_reply(NULL); get_reply(NULL); fl_set_object_color(frv->sl_time, FL_COL1, FL_INACTIVE); fl_set_object_label(frv->btn_ok_cnc, "OK"); fl_set_object_callback(frv->btn_ok_cnc, cb_remote_view_ok, 0); goto view_end; view_err: close(sock_userDTP); busy = 0; activate_object(fm->local_btns); activate_object(fm->remote_btns); activate_object(fm->br_remote); activate_object(fm->br_remote_size); view_end: if (aborted) { aborted = 0; fl_hide_form(frv->fd_remote_view); activate_form(fm->fd_main); busy = 0; activate_object(fm->local_btns); activate_object(fm->remote_btns); activate_object(fm->br_remote); activate_object(fm->br_remote_size); } } void cb_select(FL_OBJECT * ob, long arg) { int i, x, y, lmax = fl_get_browser_maxline(fm->br_local); int rmax = fl_get_browser_maxline(fm->br_remote); int bmax = fl_get_browser_maxline(fm->br_buffer_name); const char *pattern; FL_OBJECT *ret_ob; fl_freeze_form(fm->fd_main); switch (arg) { case 1: for (i = 1; i <= lmax; i++) { fl_select_browser_line(fm->br_local, i); fl_select_browser_line(fm->br_local_size, i); } break; case 2: fl_deselect_browser(fm->br_local); fl_deselect_browser(fm->br_local_size); break; case 3: fl_set_input(fi->input, ""); x = fm->fd_main->x + 5; y = fm->fd_main->y + fm->br_local->y + fm->br_local->h + 4; fl_set_form_position(fi->fd_input, x, y); fl_set_object_label(fi->txt_input, "Enter pattern:"); fl_show_form(fi->fd_input, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); deactivate_form(fm->fd_main); ret_ob = fl_do_forms(); activate_form(fm->fd_main); fl_hide_form(fi->fd_input); if (ret_ob == fi->cancel) { fl_unfreeze_form(fm->fd_main); return; } pattern = fl_get_input(fi->input); for (i = 1; i <= lmax; i++) if (fnmatch(pattern, local_files[i - 1]->file_name, 0) == 0) { fl_select_browser_line(fm->br_local, i); fl_select_browser_line(fm->br_local_size, i); } break; case 4: for (i = 1; i <= rmax; i++) { fl_select_browser_line(fm->br_remote, i); fl_select_browser_line(fm->br_remote_size, i); } break; case 5: fl_deselect_browser(fm->br_remote); fl_deselect_browser(fm->br_remote_size); break; case 6: fl_set_input(fi->input, ""); x = fm->fd_main->x + fm->txt_remote_dir->x + (fm->txt_remote_dir->w + -fi->fd_input->w) / 2; y = fm->fd_main->y + fm->br_remote->y + fm->br_remote->h + 4; fl_set_form_position(fi->fd_input, x, y); fl_set_object_label(fi->txt_input, "Enter pattern:"); fl_show_form(fi->fd_input, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); deactivate_form(fm->fd_main); ret_ob = fl_do_forms(); activate_form(fm->fd_main); fl_hide_form(fi->fd_input); if (ret_ob == fi->cancel) { fl_unfreeze_form(fm->fd_main); return; } pattern = fl_get_input(fi->input); for (i = 1; i <= rmax; i++) if (fnmatch(pattern, remote_files[i - 1]->file_name, 0) == 0) { fl_select_browser_line(fm->br_remote, i); fl_select_browser_line(fm->br_remote_size, i); } break; case 7: for (i = 1; i <= bmax; i++) fl_select_browser_line(fm->br_buffer_name, i); break; case 8: fl_deselect_browser(fm->br_buffer_name); } fl_unfreeze_form(fm->fd_main); } /* fd_download callbacks: */ void cb_dwnld_cancel(FL_OBJECT * ob, long arg) { char send_buf[20]; if (aborted) return; sprintf(send_buf, "%c%c%c", IAC, IP, IAC); send_com_no_reply(send_buf, NULL, 0, 0); sprintf(send_buf, "%c", DM); send_com_no_reply(send_buf, NULL, MSG_OOB, 0); sprintf(send_buf, "ABOR"); send_com_no_reply(send_buf, NULL, 0, 1); aborted = 1; } void cb_detach(FL_OBJECT * ob, long arg) { ninteract = 1; if (fcntl(sock_servPI, F_SETFL, fcntl(sock_servPI, F_GETFL) & ~O_NONBLOCK) < 0) { add_to_log_err("fcntl"); exit(1); } fcntl(sock_servDTP, F_SETFL, fcntl(sock_servPI, F_GETFL) & ~O_NONBLOCK); fl_finish(); } /* fd_conn_par callbacks: */ void cb_anonymous(FL_OBJECT * ob, long arg) { if (fcp->br_history->visible) cb_history(ob, 0); if (fl_get_button(ob)) { fl_set_input(fcp->user_name, "anonymous"); fl_set_input(fcp->pass_unenc, e_mail ? e_mail : ""); fl_show_object(fcp->pass_unenc); if (fcp->pass_enc->focus) fl_set_focus_object(fcp->fd_conn_par, fcp->pass_unenc); fl_hide_object(fcp->pass_enc); } else { fl_set_input(fcp->pass_enc, ""); fl_show_object(fcp->pass_enc); if (fcp->pass_unenc->focus) fl_set_focus_object(fcp->fd_conn_par, fcp->pass_enc); fl_hide_object(fcp->pass_unenc); } } void cb_ok(FL_OBJECT * ob, long arg) { const char *input; char *title, *syst_reply; char *password; int i; free(address); free(user_name); free(pass_enc); free(pass_unenc); free(local_dir_path_inp); free(remote_dir_path_inp); fl_set_object_label(fm->con_close, "Close"); fl_set_object_callback(fm->con_close, cb_close, 0); anonym_login = fl_get_button(fcp->anonymous); fl_clear_browser(fm->br_log); input = fl_get_input(fcp->address); address = malloc(strlen(input) + 1); strcpy(address, input); input = fl_get_input(fcp->user_name); user_name = malloc(strlen(input) + 1); strcpy(user_name, input); if (anonym_login) { input = fl_get_input(fcp->pass_unenc); pass_unenc = malloc(strlen(input) + 1); strcpy(pass_unenc, input); *(pass_enc = malloc(1)) = '\0'; } else { input = fl_get_input(fcp->pass_enc); pass_enc = malloc(strlen(input) + 1); strcpy(pass_enc, input); *(pass_unenc = malloc(1)) = '\0'; } input = fl_get_input(fcp->local_dir); local_dir_path_inp = malloc(strlen(input) + 1); strcpy(local_dir_path_inp, input); chdir(local_dir_path_inp); input = fl_get_input(fcp->remote_dir); remote_dir_path_inp = malloc(strlen(input) + 1); strcpy(remote_dir_path_inp, input); busy = 1; deactivate_object(fm->local_btns); activate_form(fm->fd_main); fl_hide_form(fcp->fd_conn_par); XFlush(fl_get_display()); read_local_dir(); con_canceled = 0; add_to_history(); if (open_ftp_connection() < 0) goto err_ok1; con_opened = 1; cur_type = ASCII; if (get_reply(NULL) != 220) goto err_ok; if ((i = send_command("USER", user_name, NULL)) != 331 && i != 230) goto err_ok; if (i == 331) { password = anonym_login ? pass_unenc : pass_enc; i = send_command("PASS", strcmp(password, "") ? password : " ", NULL); switch (i) { case 230: break; case 332: if (send_command("ACCT", e_mail, NULL) == 230) break; default: goto err_ok; } } send_command("SYST", NULL, &syst_reply); if (strstr(syst_reply, "UNIX") != NULL) sys_unix = 1; else sys_unix = 0; if (*remote_dir_path_inp != '\0') send_command("CWD", remote_dir_path_inp, NULL); read_remote_dir(1); title = malloc(strlen(address) + 20); sprintf(title, "Xrmftp : %s", address); fl_set_form_title(fm->fd_main, title); fl_set_object_label(fm->txt_status, ""); activate_object(fm->remote_btns); activate_object(fm->local_btns); activate_object(fm->br_remote); activate_object(fm->br_remote_size); busy = 0; free(title); return; err_ok: send_com_no_reply("QUIT", NULL, 0, 1); close(sock_servPI); err_ok1: activate_object(fm->local_btns); con_opened = 0; fl_set_form_title(fm->fd_main, ""); fl_set_object_label(fm->txt_status, ""); fl_set_object_label(fm->con_close, "Connect"); fl_set_object_callback(fm->con_close, cb_connect, 0); } void cb_cancel(FL_OBJECT * ob, long arg) { activate_form(fm->fd_main); fl_hide_form(fcp->fd_conn_par); } void cb_options(FL_OBJECT * ob, long arg) { char input[20], *pc1; if (arg == 1) { if (fcp->br_history->visible) cb_history(ob, 0); fo->fd_options->u_vdata = fcp->fd_conn_par; if (f_fold_hidden) { fl_addto_tabfolder(fo->fld_options, "Files", fofl->fd_options_files); f_fold_hidden = 0; } } else { fo->fd_options->u_vdata = fm->fd_main; if (!f_fold_hidden) { if (fl_get_folder(fo->fld_options) == fofl->fd_options_files) fl_set_folder_bynumber(fo->fld_options, 1); fl_delete_folder(fo->fld_options, fofl->fd_options_files); f_fold_hidden = 1; } } sprintf(input, "%d", port); fl_set_input(fon->port, input); fl_set_input(fon->e_mail, e_mail); pc1 = strrchr(std_bookm_file, '/'); fl_set_input(fofl->bookm_file, pc1 == NULL ? std_bookm_file : ++pc1); fl_set_choice(fof->font_txt, (font_size - 8) / 2); fl_set_choice(fof->font_br, (br_fsize - 8) / 2); fl_set_button(fofl->btn_show_hidden_local, show_hidden_local); fl_set_button(fofl->btn_show_hidden_remote, show_hidden_remote); fl_set_button(fon->btn_passive, passive); deactivate_form(fo->fd_options->u_vdata); fl_show_form(fo->fd_options, FL_PLACE_MOUSE, FL_TRANSIENT, ""); } void cb_history(FL_OBJECT * ob, long arg) { int i; fl_freeze_form(fcp->fd_conn_par); i = fl_get_button(fcp->anonymous); fl_set_focus_object(fcp->fd_conn_par, fcp->address); if (fcp->br_history->visible) { fl_hide_object(fcp->br_history); fl_show_object(fcp->user_name); fl_show_object(fcp->local_dir); fl_show_object(fcp->remote_dir); fl_show_object(i ? fcp->pass_unenc : fcp->pass_enc); } else { fl_show_object(fcp->br_history); fl_hide_object(fcp->user_name); fl_hide_object(fcp->local_dir); fl_hide_object(fcp->remote_dir); fl_hide_object(i ? fcp->pass_unenc : fcp->pass_enc); } fl_unfreeze_form(fcp->fd_conn_par); } void cb_bookm(FL_OBJECT * ob, long arg) { if (strcmp(addr_file_name, std_bookm_file)) deactivate_object(fb->btn_delete); read_bookmarks(addr_file_name); if (fcp->br_history->visible) cb_history(ob, 0); fl_show_form(fb->fd_bookmarks, FL_PLACE_MOUSE, FL_TRANSIENT, ""); deactivate_form(fcp->fd_conn_par); } void cb_load(FL_OBJECT * ob, long arg) { const char *selected_file, *pc1; deactivate_form(fcp->fd_conn_par); fl_set_fselector_fontsize(font_size); pc1 = strrchr(std_bookm_file, '/'); selected_file = fl_show_fselector("Filename to load bookmarks from", home_dir, "*.html", pc1 == NULL ? std_bookm_file : ++pc1); if (selected_file != NULL) { free(addr_file_name); addr_file_name = malloc(strlen(selected_file) + 1); strcpy(addr_file_name, selected_file); } activate_form(fcp->fd_conn_par); } void cb_add(FL_OBJECT * ob, long arg) { const char *addr, *dir; struct addr_item *pAd_it; read_bookmarks(std_bookm_file); pAd_it = bookm_first; addr = fl_get_input(fcp->address); dir = fl_get_input(fcp->remote_dir); while (pAd_it != NULL) { if (strcmp(addr, pAd_it->address) == 0 && strcmp(dir, pAd_it->dir) == 0) return; pAd_it = pAd_it->next; } pAd_it = malloc(sizeof(struct addr_item)); pAd_it->next = NULL; if (bookm_last != NULL) bookm_last->next = pAd_it; bookm_last = pAd_it; if (bookm_first == NULL) bookm_first = pAd_it; pAd_it->address = malloc(strlen(addr) + 1); pAd_it->dir = malloc(strlen(dir) + 1); strcpy(pAd_it->address, addr); strcpy(pAd_it->dir, dir); fl_add_browser_line(fb->br_bookmarks, addr); fl_addto_browser_chars(fb->br_bookmarks, dir); write_bookmarks(); read_bookmarks(addr_file_name); } void cb_br_hist(FL_OBJECT * ob, long arg) { int i; struct hist_item *pHist_it; i = fl_get_browser(ob); fl_hide_object(fcp->br_history); pHist_it = hist_first; for (; i > 1; i--) pHist_it = pHist_it->next; fl_set_button(fcp->anonymous, pHist_it->anonym_login); cb_anonymous(fcp->anonymous, 0); fl_set_input(fcp->address, pHist_it->address); fl_set_input(fcp->user_name, pHist_it->user_name); fl_set_input(fcp->pass_unenc, pHist_it->pass_unenc); fl_set_input(fcp->local_dir, pHist_it->local_dir); fl_set_input(fcp->remote_dir, pHist_it->remote_dir); fl_show_object(fcp->user_name); fl_show_object(fcp->local_dir); fl_show_object(fcp->remote_dir); fl_show_object(pHist_it->anonym_login ? fcp->pass_unenc : fcp->pass_enc); } /* fd_bookmarks callbacks */ void cb_bm_cancel(FL_OBJECT * ob, long arg) { if (strcmp(addr_file_name, std_bookm_file)) activate_object(fb->btn_delete); fl_hide_form(fb->fd_bookmarks); activate_form(fcp->fd_conn_par); } void cb_bm_delete(FL_OBJECT * ob, long arg) { int i; struct addr_item *pAd_it, *pPrev_it = NULL, *pNext_it; pAd_it = bookm_first; for (i = 1; i <= fl_get_browser_maxline(fb->br_bookmarks);) { if (fl_isselected_browser_line(fb->br_bookmarks, i)) { fl_delete_browser_line(fb->br_bookmarks, i); pNext_it = pAd_it->next; if (pNext_it == NULL) bookm_last = pPrev_it; if (pPrev_it != NULL) pPrev_it->next = pAd_it->next; else bookm_first = pAd_it->next; free(pAd_it->address); free(pAd_it->dir); free(pAd_it); pAd_it = pNext_it; } else { pPrev_it = pAd_it; pAd_it = pAd_it->next; i++; } } write_bookmarks(); } void cb2_br_bookmarks(FL_OBJECT * ob, long arg) { int i; struct addr_item *pAd_it = bookm_first; i = abs(fl_get_browser(ob)); for (; i > 1; i--) pAd_it = pAd_it->next; fl_set_input(fcp->address, pAd_it->address); fl_set_input(fcp->remote_dir, pAd_it->dir); if (strcmp(addr_file_name, std_bookm_file)) activate_object(fb->btn_delete); fl_hide_form(fb->fd_bookmarks); activate_form(fcp->fd_conn_par); } void cb_bm_ok(FL_OBJECT * ob, long arg) { int i, m; struct addr_item *pAd_it = bookm_first; m = fl_get_browser_maxline(fb->br_bookmarks); for (i = 1; !fl_isselected_browser_line(fb->br_bookmarks, i); i++) if (i > m) return; for (; i > 1; i--) pAd_it = pAd_it->next; fl_set_input(fcp->address, pAd_it->address); fl_set_input(fcp->remote_dir, pAd_it->dir); if (strcmp(addr_file_name, std_bookm_file)) activate_object(fb->btn_delete); fl_hide_form(fb->fd_bookmarks); activate_form(fcp->fd_conn_par); } /* fd_options callbacks */ void cb_op_ok(FL_OBJECT * ob, long arg) { int tsize, bsize, r, g, b; const char *input; FILE *f_options; fl_redraw_form(fm->fd_main); activate_form(fo->fd_options->u_vdata); fl_hide_form(fo->fd_options); tsize = atoi(fl_get_choice_text(fof->font_txt)); bsize = atoi(fl_get_choice_text(fof->font_br)); if (tsize != font_size || bsize != br_fsize) { br_fsize = bsize; font_size = tsize; change_font_size(); } port = atoi(fl_get_input(fon->port)); input = fl_get_input(fon->e_mail); strcpy(e_mail, input); input = fl_get_input(fofl->bookm_file); free(std_bookm_file); std_bookm_file = malloc(strlen(input) + strlen(home_dir) + 2); sprintf(std_bookm_file, "%s%s", home_dir, input); free(addr_file_name); addr_file_name = malloc(strlen(std_bookm_file) + 1); strcpy(addr_file_name, std_bookm_file); read_bookmarks(std_bookm_file); show_hidden_local = fl_get_button(fofl->btn_show_hidden_local); show_hidden_remote = fl_get_button(fofl->btn_show_hidden_remote); passive = fl_get_button(fon->btn_passive); if ((f_options = fopen(opt_file_name, "w")) == NULL) { fl_set_object_label(fmsg->txt, "Can not save options file !"); deactivate_form(fo->fd_options); fl_show_form(fmsg->fd_message, FL_PLACE_MOUSE, FL_TRANSIENT, ""); fl_do_forms(); fl_hide_form(fmsg->fd_message); activate_form(fo->fd_options); return; } fprintf(f_options, "%s\n", e_mail); fprintf(f_options, "%d\n", font_size); fprintf(f_options, "%d\n", br_fsize); fprintf(f_options, "%d\n", show_hidden_local); fprintf(f_options, "%d\n", show_hidden_remote); fprintf(f_options, "%d\n", passive); fprintf(f_options, "%s\n", input); fl_getmcolor(FL_FREE_COL1, &r, &g, &b); fprintf(f_options, "%d,%d,%d\n", r, g, b); fl_getmcolor(FL_FREE_COL1 + 1, &r, &g, &b); fprintf(f_options, "%d,%d,%d\n", r, g, b); fl_getmcolor(FL_FREE_COL1 + 2, &r, &g, &b); fprintf(f_options, "%d,%d,%d\n", r, g, b); fl_getmcolor(FL_FREE_COL1 + 3, &r, &g, &b); fprintf(f_options, "%d,%d,%d\n", r, g, b); fl_getmcolor(FL_FREE_COL1 + 4, &r, &g, &b); fprintf(f_options, "%d,%d,%d\n", r, g, b); fl_getmcolor(FL_FREE_COL1 + 5, &r, &g, &b); fprintf(f_options, "%d,%d,%d\n", r, g, b); fclose(f_options); } void cb_op_cancel(FL_OBJECT * ob, long arg) { fl_hide_form(fo->fd_options); fl_redraw_form(fm->fd_main); activate_form(fo->fd_options->u_vdata); } void cb_chg_col(FL_OBJECT * ob, long arg) { int r, g, b; int *rgb = malloc(3 * sizeof(int)); char label[30]; fc->txt_col->u_ldata = arg; deactivate_form(fo->fd_options); fl_set_object_lcol(fc->txt_col, FL_FREE_COL1 + arg); fl_set_object_lcol(fc->txt_col_sel, FL_FREE_COL1 + arg); switch (arg) { case 0: strcpy(label, ""); break; case 1: strcpy(label, ""); break; case 2: strcpy(label, "Directories"); break; case 3: strcpy(label, "Links"); break; case 4: strcpy(label, "Executable files"); break; case 5: strcpy(label, "Other files"); } fl_set_object_label(fc->txt_col, label); fl_set_object_label(fc->txt_col_sel, label); fl_getmcolor(FL_FREE_COL1 + arg, &r, &g, &b); rgb[0] = r; rgb[1] = g; rgb[2] = b; fc->txt_col->u_vdata = rgb; fl_set_slider_value(fc->sld_red, r); fl_set_slider_value(fc->sld_green, g); fl_set_slider_value(fc->sld_blue, b); fl_show_form(fc->fd_colors, FL_PLACE_MOUSE, FL_TRANSIENT, ""); } void cb_col_ok(FL_OBJECT * ob, long arg) { int i, no = fc->txt_col->u_ldata; fl_hide_form(fc->fd_colors); if (no == 0) for (i = 0; i < 6; i++) fl_redraw_object(foc->btn_col[i]); else fl_redraw_object(foc->btn_col[no]); activate_form(fo->fd_options); } void cb_col_cancel(FL_OBJECT * ob, long arg) { int *rgb; activate_form(fo->fd_options); fl_hide_form(fc->fd_colors); rgb = fc->txt_col->u_vdata; fl_mapcolor(FL_FREE_COL1 + fc->txt_col->u_ldata, rgb[0], rgb[1], rgb[2]); free(rgb); } void cb_sld_col(FL_OBJECT * ob, long arg) { int r, g, b; FL_COLOR col_ind = FL_FREE_COL1 + fc->txt_col->u_ldata; r = fl_get_slider_value(fc->sld_red); g = fl_get_slider_value(fc->sld_green); b = fl_get_slider_value(fc->sld_blue); fl_mapcolor(col_ind, r, g, b); fl_redraw_object(fc->txt_col); fl_redraw_object(fc->txt_col_sel); } /* fd_remote_view callback */ void cb_remote_view_ok(FL_OBJECT * ob, long arg) { fl_hide_form(frv->fd_remote_view); busy = 0; activate_object(fm->local_btns); activate_object(fm->remote_btns); activate_object(fm->br_remote); activate_object(fm->br_remote_size); activate_form(fm->fd_main); } /* fd_local_view callback */ void cb_local_view_ok(FL_OBJECT * ob, long arg) { fl_hide_form(flv->fd_local_view); } /* fd_about callback */ void cb_about_ok(FL_OBJECT * ob, long arg) { activate_form(fm->fd_main); fl_hide_form(fa->fd_about); } /*************/ char * get_cwdir() { int i = 50; char *wd; i = 50; wd = malloc(i); while (getcwd(wd, i) == NULL) { if (errno == EACCES) { free(wd); wd = NULL; return wd; } if (errno != ERANGE) { perror("getcwd error"); exit(1); } free(wd); wd = malloc(i += 10); } return wd; } char * get_home_dir() { struct passwd *pw_ent; char *h_dir; if ((pw_ent = getpwuid(getuid()))) { h_dir = malloc(strlen(pw_ent->pw_dir) + 3); strcpy(h_dir, pw_ent->pw_dir); strcat(h_dir, "/"); return h_dir; } return NULL; } void read_bookmarks(const char *bookm_file) { int bf, bytes_read; char read_buf[BUF_SIZE + 1], *full_addr, buf[BUF_SIZE + 1], *pc1, *pc2; struct addr_item *pAd_it; fl_clear_browser(fb->br_bookmarks); bookm_last = NULL; while (bookm_first != NULL) { free(bookm_first->address); free(bookm_first->dir); pAd_it = bookm_first->next; free(bookm_first); bookm_first = pAd_it; } if ((bf = open(bookm_file, O_RDONLY)) >= 0) { while ((bytes_read = read(bf, read_buf, BUF_SIZE)) != 0) { read_buf[bytes_read] = '\0'; pc1 = read_buf; while ((pc1 = strstr(pc1, "next = NULL; if (bookm_last != NULL) bookm_last->next = pAd_it; bookm_last = pAd_it; if (bookm_first == NULL) bookm_first = pAd_it; pc1 += 6; while (*pc1 == ' ') pc1++; pc2 = pc1; while (*pc2 != '>' && *pc2 != '/' && *pc2 != ' ' && *pc1 != '\0') pc2++; if (*(pc2 - 1) == '"') pc2--; pAd_it->address = malloc(pc2 - pc1 + 1); strncpy(pAd_it->address, pc1, pc2 - pc1); pAd_it->address[pc2 - pc1] = '\0'; if (*pc2 == '>' || *pc2 == ' ') { pAd_it->dir = malloc(1); *pAd_it->dir = '\0'; pc1 = pc2; } else { buf[0] = '\0'; pc1 = pc2; while (*pc1 != '>' && *pc1 != ' ' && *pc1 != '\0') pc1++; if (*pc1 == '\0') { strcpy(buf, pc2); if ((bytes_read = read(bf, read_buf, BUF_SIZE)) == 0) { close(bf); return; } read_buf[bytes_read] = '\0'; pc2 = read_buf; if ((pc1 = strchr(pc2, ' ')) == NULL && (pc1 = strchr(pc2, '>')) == NULL) return; } if (*(pc1 - 1) == '"') pc1--; *pc1 = '\0'; strcat(buf, pc2); pAd_it->dir = malloc(strlen(buf) + 1); strcpy(pAd_it->dir, buf); pc1++; } } } close(bf); pAd_it = bookm_first; while (pAd_it != NULL) { full_addr = malloc(strlen(pAd_it->address) + strlen(pAd_it->dir) + 2); sprintf(full_addr, "%s%s", pAd_it->address, pAd_it->dir); fl_add_browser_line(fb->br_bookmarks, full_addr); free(full_addr); pAd_it = pAd_it->next; } } } void write_bookmarks() { struct addr_item *pAd_it; int i = 0; FILE *fbm; pAd_it = bookm_first; if ((fbm = fopen(std_bookm_file, "w")) != NULL) { fprintf(fbm, "\n"); fprintf(fbm, "\n"); fprintf(fbm, "Xrmtfp bookmarks\n"); fprintf(fbm, "\n"); fprintf(fbm, "\n"); while (pAd_it != NULL) { fprintf(fbm, "%d %s%s
\n", ++i, pAd_it->address, pAd_it->dir, pAd_it->address, pAd_it->dir); pAd_it = pAd_it->next; } fprintf(fbm, "\n"); fprintf(fbm, "\n"); } fclose(fbm); } char * read_hist_field(FILE * fh) { char rl[MAXLINE], *fld; fgets(rl, MAXLINE, fh); rl[strlen(rl) - 1] = '\0'; fld = malloc(strlen(rl) + 1); strcpy(fld, rl); return fld; } void read_hist() { FILE *f_history; int i; struct hist_item *pHist_it; char rl[10]; hist_last = NULL; while (hist_first != NULL) { free(hist_first->address); free(hist_first->user_name); free(hist_first->pass_unenc); free(hist_first->local_dir); free(hist_first->remote_dir); pHist_it = hist_first->next; free(hist_first); hist_first = pHist_it; } if ((f_history = fopen(hist_file_name, "r+")) != NULL) { fgets(rl, MAXLINE, f_history); n_hist = atoi(rl); if (n_hist > HIST_SIZE) n_hist = HIST_SIZE; for (i = 0; i < n_hist; i++) { pHist_it = malloc(sizeof(struct hist_item)); pHist_it->address = read_hist_field(f_history); pHist_it->user_name = read_hist_field(f_history); pHist_it->pass_unenc = read_hist_field(f_history); pHist_it->local_dir = read_hist_field(f_history); pHist_it->remote_dir = read_hist_field(f_history); fgets(rl, MAXLINE, f_history); pHist_it->anonym_login = atoi(rl); pHist_it->next = NULL; if (hist_last != NULL) hist_last->next = pHist_it; hist_last = pHist_it; if (hist_first == NULL) hist_first = pHist_it; } fl_clear_browser(fcp->br_history); pHist_it = hist_first; while (pHist_it != NULL) { fl_add_browser_line(fcp->br_history, pHist_it->address); fl_addto_browser_chars(fcp->br_history, " "); fl_addto_browser_chars(fcp->br_history, pHist_it->remote_dir); pHist_it = pHist_it->next; } fclose(f_history); return; } } int read_op(FILE * f_options, int *pOp) { char op_line[MAXLINE]; if (fgets(op_line, MAXLINE - 1, f_options) == NULL) return -1; op_line[strlen(op_line) - 1] = '\0'; *pOp = atoi(op_line); return 1; } void read_init_files() { FILE *f_options; char op_line[MAXLINE]; int r, g, b; if ((f_options = fopen(opt_file_name, "r")) != NULL) { fgets(e_mail, 80, f_options); e_mail[strlen(e_mail) - 1] = '\0'; if (read_op(f_options, &font_size) < 0) font_size = 10; else if (font_size < 10 || font_size > 14) font_size = 10; if (read_op(f_options, &br_fsize) < 0) br_fsize = 10; else if (br_fsize < 10 || br_fsize > 14) br_fsize = 10; if (read_op(f_options, &show_hidden_local) < 0) show_hidden_local = 1; if (read_op(f_options, &show_hidden_remote) < 0) show_hidden_remote = 1; if (read_op(f_options, &passive) < 0) passive = 1; if (fgets(op_line, 80, f_options) != NULL) { op_line[strlen(op_line) - 1] = '\0'; free(std_bookm_file); std_bookm_file = malloc(strlen(home_dir) + strlen(op_line) + 2); sprintf(std_bookm_file, "%s%s", home_dir, op_line); addr_file_name = malloc(strlen(std_bookm_file) + 1); strcpy(addr_file_name, std_bookm_file); if (fscanf(f_options, "%d,%d,%d\n", &r, &g, &b) == 3) fl_mapcolor(FL_FREE_COL1, r, g, b); if (fscanf(f_options, "%d,%d,%d\n", &r, &g, &b) == 3) fl_mapcolor(FL_FREE_COL1 + 1, r, g, b); if (fscanf(f_options, "%d,%d,%d\n", &r, &g, &b) == 3) fl_mapcolor(FL_FREE_COL1 + 2, r, g, b); if (fscanf(f_options, "%d,%d,%d\n", &r, &g, &b) == 3) fl_mapcolor(FL_FREE_COL1 + 3, r, g, b); if (fscanf(f_options, "%d,%d,%d\n", &r, &g, &b) == 3) fl_mapcolor(FL_FREE_COL1 + 4, r, g, b); if (fscanf(f_options, "%d,%d,%d\n", &r, &g, &b) == 3) fl_mapcolor(FL_FREE_COL1 + 5, r, g, b); } fclose(f_options); } read_hist(); if (hist_first != NULL) { fl_set_input(fcp->address, hist_first->address); fl_set_input(fcp->user_name, hist_first->user_name); fl_set_input(fcp->pass_unenc, hist_first->pass_unenc); fl_set_input(fcp->local_dir, hist_first->local_dir); fl_set_input(fcp->remote_dir, hist_first->remote_dir); } read_bookmarks(addr_file_name); flog = fopen(log_file_name, "w"); } int main(int argc, char *argv[]) { FL_OBJECT *vscroll_local, *vscroll_remote, *ob; FL_IOPT options; int x, y, r, g, b, i; home_dir = get_home_dir(); addr_file_name = malloc(strlen(home_dir) + 30); std_bookm_file = malloc(strlen(home_dir) + 30); opt_file_name = malloc(strlen(home_dir) + 30); hist_file_name = malloc(strlen(home_dir) + 30); log_file_name = malloc(strlen(home_dir) + 30); strcpy(addr_file_name, home_dir); strcpy(opt_file_name, home_dir); strcpy(hist_file_name, home_dir); strcpy(log_file_name, home_dir); strcat(addr_file_name, "ftp_bookmarks.html"); strcat(opt_file_name, ".Xrmftp_options"); strcat(hist_file_name, ".Xrmftp_history"); strcat(log_file_name, ".Xrmftp_log"); strcpy(std_bookm_file, addr_file_name); *(address = malloc(1)) = '\0'; *(user_name = malloc(1)) = '\0'; *(pass_enc = malloc(1)) = '\0'; *(pass_unenc = malloc(1)) = '\0'; *(local_dir_path_inp = malloc(1)) = '\0'; *(remote_dir_path_inp = malloc(1)) = '\0'; *(remote_dir_path = malloc(1)) = '\0'; options.borderWidth = -1; fl_set_defaults(FL_PDBorderWidth, &options); fl_initialize(&argc, argv, "", 0, 0); create_forms(); sprintf(dir_col, "@C%d", FL_FREE_COL1 + 2); sprintf(lnk_col, "@C%d", FL_FREE_COL1 + 3); sprintf(exe_col, "@C%d", FL_FREE_COL1 + 4); sprintf(other_col, "@C%d", FL_FREE_COL1 + 5); fl_getmcolor(FL_COL1, &r, &g, &b); fl_mapcolor(FL_FREE_COL1, r, g, b); fl_getmcolor(FL_YELLOW, &r, &g, &b); fl_mapcolor(FL_FREE_COL1 + 1, r, g, b); fl_getmcolor(FL_BLUE, &r, &g, &b); fl_mapcolor(FL_FREE_COL1 + 2, r, g, b); fl_getmcolor(FL_GREEN, &r, &g, &b); fl_mapcolor(FL_FREE_COL1 + 3, r, g, b); fl_getmcolor(FL_RED, &r, &g, &b); fl_mapcolor(FL_FREE_COL1 + 4, r, g, b); fl_getmcolor(FL_BLACK, &r, &g, &b); fl_mapcolor(FL_FREE_COL1 + 5, r, g, b); fl_set_object_color(fc->txt_col, FL_FREE_COL1, FL_INACTIVE_COL); fl_set_object_color(fc->txt_col_sel, FL_FREE_COL1 + 1, FL_INACTIVE_COL); read_init_files(); ob = fm->fd_main->first; while (1) { if (ob->objclass == FL_BROWSER) fl_set_object_color(ob, FL_FREE_COL1, FL_FREE_COL1 + 1); if (ob == fm->fd_main->last) break; ob = ob->next; } for (i = 2; i < 6; i++) { fl_set_object_color(foc->btn_col[i], FL_FREE_COL1, FL_FREE_COL1); fl_set_object_lcol(foc->btn_col[i], FL_FREE_COL1 + i); } fl_set_object_lcol(fm->br_log, FL_FREE_COL1 + 5); signal(SIGPIPE, SIG_IGN); fl_set_button(fofl->btn_show_hidden_local, show_hidden_local); fl_set_button(fofl->btn_show_hidden_remote, show_hidden_remote); fl_set_button(fon->btn_passive, passive); change_font_size(); fl_deactivate_object(fd->sl_time); fl_deactivate_object(frv->sl_time); fl_hide_object(fcp->pass_unenc); fl_hide_object(fcp->br_history); fl_set_input_maxchars(fon->e_mail, 80); fl_addto_tabfolder(fo->fld_options, "Network", fon->fd_options_net); fl_addto_tabfolder(fo->fld_options, "Fonts", fof->fd_options_fonts); fl_addto_tabfolder(fo->fld_options, "Colors", foc->fd_options_colors); fl_addto_tabfolder(fo->fld_options, "Files", fofl->fd_options_files); fl_set_object_prehandler(fm->br_local_size, prehndl_local_size); fl_set_object_prehandler(fm->br_local, prehndl_local); fl_set_object_prehandler(fm->br_remote_size, prehndl_remote_size); fl_set_object_prehandler(fm->br_remote, prehndl_remote); vscroll_local = fl_get_object_component(fm->br_local_size, FL_SCROLLBAR, FL_VERT_THIN_SCROLLBAR, 0); vscroll_remote = fl_get_object_component(fm->br_remote_size, FL_SCROLLBAR, FL_VERT_THIN_SCROLLBAR, 0); cb_old_local = fl_set_object_callback(vscroll_local, cb_vscroll_local, 0); cb_old_remote = fl_set_object_callback(vscroll_remote, cb_vscroll_remote, 0); fl_set_browser_vscrollbar(fm->br_local, FL_OFF); fl_set_browser_hscrollbar(fm->br_local, FL_ON); fl_set_browser_hscrollbar(fm->br_local_size, FL_ON); fl_set_browser_scrollbarsize(fm->br_local, 15, 15); fl_set_browser_scrollbarsize(fm->br_local_size, 15, 15); fl_set_browser_dblclick_callback(fm->br_local, cb2_br_local, 0); fl_set_browser_dblclick_callback(fm->br_local_size, cb2_br_local, 0); fl_set_browser_dblclick_callback(fb->br_bookmarks, cb2_br_bookmarks, 0); fl_set_browser_vscrollbar(fm->br_remote, FL_OFF); fl_set_browser_hscrollbar(fm->br_remote, FL_ON); fl_set_browser_hscrollbar(fm->br_remote_size, FL_ON); fl_set_browser_scrollbarsize(fm->br_remote, 15, 15); fl_set_browser_scrollbarsize(fm->br_remote_size, 15, 15); fl_set_browser_dblclick_callback(fm->br_remote, cb2_br_remote, 0); fl_set_browser_dblclick_callback(fm->br_remote_size, cb2_br_remote, 0); fl_set_browser_hscrollbar(fm->br_buffer_name, FL_ON); fl_set_browser_scrollbarsize(fm->br_buffer_name, 15, 15); fl_set_browser_scrollbarsize(fm->br_log, 15, 15); fl_set_browser_scrollbarsize(fcp->br_history, 15, 15); fl_set_browser_scrollbarsize(fb->br_bookmarks, 15, 15); fl_set_choice(fof->font_txt, (font_size - 8) / 2); fl_set_choice(fof->font_br, (br_fsize - 8) / 2); deactivate_object(fm->remote_btns); deactivate_object(fm->br_remote); deactivate_object(fm->br_remote_size); fl_set_form_minsize(fm->fd_main, minx, miny); fl_show_form (fm->fd_main, FL_PLACE_FREE, FL_FULLBORDER, "Xrmftp"); deactivate_form(fm->fd_main); x = fm->fd_main->x + (fm->fd_main->w - fcp->fd_conn_par->w) / 2; y = fm->fd_main->y + (fm->fd_main->h - fcp->fd_conn_par->h) / 2; fl_set_form_position(fcp->fd_conn_par, x, y); fl_show_form(fcp->fd_conn_par, FL_PLACE_GEOMETRY, FL_TRANSIENT, ""); XFlush(fl_get_display()); read_local_dir(); while (1) fl_check_forms(); return 0; }