file.c
上传用户:tianjinjs
上传日期:2007-01-05
资源大小:309k
文件大小:19k
源码类别:

Modem编程

开发平台:

Unix_Linux

  1. /*
  2.  * file.c Functions to handle file selector.
  3.  *
  4.  * This file is part of the minicom communications package,
  5.  * Copyright 1991-1995 Miquel van Smoorenburg.
  6.  *
  7.  * This file created from code mostly cadged from "dial.c"
  8.  * by Miquel van Smoorenburg.  Written by James S. Seymour.
  9.  * Copyright (c) 1998 by James S. Seymour (jseymour@jimsun.LinxNet.com)
  10.  *      Some mods for i18n  
  11.  *         Copyright (c) 1998 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  12.  *
  13.  * This program is free software; you can redistribute it and/or
  14.  * modify it under the terms of the GNU General Public License
  15.  * as published by the Free Software Foundation; either version
  16.  * 2 of the License, or (at your option) any later version.
  17.  */
  18. #include "port.h"
  19. #include "minicom.h"
  20. #include "intl.h"
  21. #include "getsdir.h"
  22. _PROTO(extern int wildmat, (char *s, char *p));
  23. /* We want the ANSI offsetof macro to do some dirty stuff. */
  24. #ifndef offsetof
  25. #  define offsetof(type, member) ((int) &((type *)0)->member)
  26. #endif
  27. /* Values for the "flags". */
  28. #define FL_ECHO 0x01 /* Local echo on/off. */
  29. #define FL_DEL 0x02 /* Backspace or DEL */
  30. #define FL_WRAP 0x04 /* Use autowrap. */
  31. #define FL_ANSI 0x08 /* Type of term emulation */
  32. #define FL_TAG 0x80 /* This entry is tagged. */
  33. #define FL_SAVE 0x0f /* Which portions of flags to save. */
  34. #define FILE_MWTR 1 /* main window top row */
  35. #define SUBM_OKAY 5 /* last entry in sub-menu */
  36. static int nrents = 1;
  37. _PROTO(static void file_tell, (char *s));
  38. /*
  39.  * replaced by macro (on test basis)
  40. _PROTO(static GETSDIR_ENTRY *getno, (int no, GETSDIR_ENTRY *dirdat));
  41.  */
  42. _PROTO(static void dhili, (int k));
  43. _PROTO(static void prdir, (WIN *dirw, int top, int cur, 
  44.     GETSDIR_ENTRY *dirdat, int longest));
  45. _PROTO(static void prone, (WIN *dirw, int top, int cur, 
  46.     GETSDIR_ENTRY *dirdat, int longest, int inverse));
  47. _PROTO(static void *set_work_dir, (void *existing, size_t min_len));
  48. _PROTO(static int new_filedir, (GETSDIR_ENTRY *o_dirdat, int flushit));
  49. _PROTO(static void goto_filedir, (char *new_dir, int absolut));
  50. _PROTO(static int tag_untag, (char *pat, int tag));
  51. _PROTO(static char *concat_list, (GETSDIR_ENTRY *d));
  52. _PROTO(static int init_filedir, (void));
  53. static WIN *dsub;
  54. #define WHAT_NR_OPTIONS 6
  55. static char *what =  N_(" [Goto]  [Prev]  [Show]  [Tag]  [Untag]  [Okay] ");
  56. /*                       123456789012345678901234567890123456789012345678
  57.                                   1         2         3         4        */
  58. static int dprev;
  59. /* Little menu. */
  60. static char *d_yesno[] = { N_("   Yes  "), N_("   No   "), CNULL };
  61. /*
  62.  * Tell a little message
  63.  */
  64. static void
  65. file_tell(s)
  66. char *s;
  67. {
  68.   WIN *w;
  69.   w = mc_tell(s);
  70.   sleep(1);
  71.   wclose(w, 1);
  72. }
  73. /*
  74.  * Highlight a choice in the horizontal menu.
  75.  */
  76. static void
  77. dhili(k)
  78. int k;
  79. {
  80.     int what_len = strlen (_(what)),
  81.         what_option_len = what_len / WHAT_NR_OPTIONS,
  82.         initial_y = (76 - (what_len >= 76 ? 74 : what_len)) / 2;
  83.        
  84.     if(k == dprev)
  85. return;
  86.     if(dprev >= 0) {
  87. wlocate(dsub, initial_y + what_option_len*dprev, 0);
  88. if(!useattr) {
  89.     wputs(dsub, " ");
  90. } else {
  91.     wsetattr(dsub, stdattr);
  92.     wprintf(dsub, "%*.*s", what_option_len - 1, what_option_len - 1,
  93.                           _(what) + what_option_len*dprev);
  94. }
  95.     }
  96.     dprev = k;
  97.     wlocate(dsub, initial_y + what_option_len*k, 0);
  98.     if(!useattr) {
  99. wputs(dsub, ">");
  100.     } else {
  101. wsetattr(dsub, XA_REVERSE | stdattr);
  102. wprintf(dsub, "%*.*s", what_option_len - 1, what_option_len - 1,
  103.                               _(what) + what_option_len*k);
  104. wsetattr(dsub, stdattr);
  105.     }
  106. }
  107. /*
  108.  */
  109. #define getno(n,d) ((n) >= nrents? (GETSDIR_ENTRY *) NULL : &((d)[n]))
  110. /*
  111.  * Get entry "no" in list.
  112. static GETSDIR_ENTRY *
  113. getno(no, dirdat)
  114. int no;
  115. GETSDIR_ENTRY *dirdat;
  116. {
  117.     if(no >= nrents)
  118. return((GETSDIR_ENTRY *) NULL);
  119.     return(&dirdat[no]);
  120. }
  121.  */
  122. /*
  123.  * Print the directory. Only draw from "cur" to bottom.
  124.  */
  125. static void
  126. prdir(dirw, top, cur, dirdat, longest)
  127. WIN *dirw;
  128. int top, cur;
  129. GETSDIR_ENTRY *dirdat;
  130. int longest;
  131. {
  132.     int f, start;
  133.     GETSDIR_ENTRY *d;
  134.     char f_str[BUFSIZ];
  135.     char t_str[BUFSIZ];
  136.     start = cur - top;
  137.     dirflush = 0;
  138.     sprintf(f_str, " %%-%ds", longest + 2);
  139.     wlocate(dirw, 0, start + FILE_MWTR);
  140.     for(f = start; f < dirw->ys - (1 + FILE_MWTR); f++) {
  141. if((d = getno(f + top, dirdat)) == (GETSDIR_ENTRY *) NULL)
  142.     break;
  143. if(d->cflags & FL_TAG)
  144.     wsetattr(dirw, XA_REVERSE | stdattr);
  145. if(S_ISDIR(d->mode)) {
  146.     snprintf(t_str, sizeof(t_str), "[%s]", d->fname);
  147.     wprintf(dirw, f_str, t_str);
  148. }
  149. else
  150.     wprintf(dirw, f_str, d->fname);
  151. wsetattr(dirw, XA_NORMAL | stdattr);
  152. wputc(dirw, 'n');
  153.     }
  154.     dirflush = 1;
  155.     wflush();
  156. }
  157. /*
  158.  * Print one directory entry.
  159.  */
  160. static void
  161. prone(dirw, top, cur, dirdat, longest, inverse)
  162. WIN *dirw;
  163. int top, cur;
  164. GETSDIR_ENTRY *dirdat;
  165. int longest;
  166. int inverse;
  167. {
  168.     char f_str[BUFSIZ];
  169.     char t_str[BUFSIZ];
  170.     dirflush = 0;
  171.     sprintf(f_str, " %%-%ds", longest + 2);
  172.     /*
  173.     if(dirdat->cflags & FL_TAG)
  174. wsetattr(dirw, XA_REVERSE | stdattr);
  175.      */
  176.     if(inverse)
  177. wsetattr(dirw, XA_REVERSE | stdattr);
  178.     if(S_ISDIR(dirdat->mode)) {
  179. snprintf(t_str, sizeof(t_str),  "[%s]", dirdat->fname);
  180. wprintf(dirw, f_str, t_str);
  181.     }
  182.     else
  183. wprintf(dirw, f_str, dirdat->fname);
  184.     wsetattr(dirw, XA_NORMAL | stdattr);
  185.     dirflush = 1;
  186.     wflush();
  187. }
  188. static WIN *main_w;
  189. static GETSDIR_ENTRY *dirdat, *d;
  190. static int cur = 0;
  191. static int ocur = 0;
  192. static int subm = SUBM_OKAY;
  193. static int quit = 0;
  194. static int top = 0;
  195. static int c = 0;
  196. static int pgud = 0;
  197. static int first = 1;
  198. static char *s;
  199. static int longest;
  200. static char file_title[BUFSIZ];
  201. static char cwd_str[BUFSIZ];
  202. static char *prev_dir = NULL;
  203. static char *work_dir = NULL;
  204. static char *d_work_dir = NULL;
  205. static char *u_work_dir = NULL;
  206. static int min_len = 1;
  207. static char wc_str[128] = "";
  208. static char wc_mem[128] = "";
  209. static int tag_cnt = 0;
  210. static int how_many = 0;
  211. static int down_loading = 0;
  212. static char *ret_buf = NULL;
  213. static void *
  214. set_work_dir(existing, min_len)
  215. void *existing;
  216. size_t min_len;
  217. {
  218.     void *vp;
  219.     vp = existing == NULL? malloc(min_len) : realloc(existing, min_len);
  220.     if(down_loading)
  221. d_work_dir = vp;
  222.     else
  223. u_work_dir = vp;
  224.     return(vp);
  225. }
  226. /*
  227.  * Initialize new file directory.
  228.  *
  229.  * Sets the current working directory.  Non-0 return = no change.
  230.  */
  231. static int
  232. new_filedir(o_dirdat, flushit)
  233. GETSDIR_ENTRY *o_dirdat;
  234. int flushit;
  235. {
  236.     static int dp_len = 0;
  237.     static char cwd_str_fmt[BUFSIZ] = "";
  238.     int new_dp_len,
  239.         fmt_len;
  240.     char disp_dir[80];
  241.     int what_len = strlen (_(what)),
  242.         initial_y = (76 - (what_len >= 76 ? 74 : what_len)) / 2;
  243.     cur      =  0;
  244.     ocur     =  0;
  245.     subm     =  SUBM_OKAY;
  246.     quit     =  0;
  247.     top      =  0;
  248.     c        =  0;
  249.     pgud     =  0;
  250.     first    =  1;
  251.     min_len  =  1;
  252.     dprev    = -1;
  253.     tag_cnt  =  0;
  254.     /* got to do some error-checking here!!!  Maybe use mcd(), too! */
  255.     if(prev_dir != NULL)
  256. free(prev_dir);
  257.     prev_dir = getcwd(NULL, BUFSIZ);
  258.     /*
  259.      * get last directory
  260.      */
  261.     work_dir = down_loading? d_work_dir : u_work_dir;
  262.     /*
  263.      * init working directory to default?
  264.      */
  265.     if(work_dir == NULL) {
  266. char *s = down_loading? (P_DOWNDIR) : (P_UPDIR);
  267. min_len = 1;
  268. if(*s != '/')
  269.     min_len += strlen(homedir) + 1;
  270. min_len += strlen(s);
  271. if(min_len < BUFSIZ)
  272.     min_len = BUFSIZ;
  273. work_dir = set_work_dir(NULL, min_len);
  274. if(*s == '/')
  275.   strncpy(work_dir, s, min_len);
  276. else
  277.   snprintf(work_dir, min_len, "%s/%s", homedir, s);
  278.     }
  279.     /* lop-off trailing "/" for consistency */
  280.     if(strlen(work_dir) > 1 && work_dir[strlen(work_dir) - 1] == '/')
  281. work_dir[strlen(work_dir) - 1] = (char) 0;
  282.     chdir(work_dir);
  283.     /* All right, draw the file directory! */
  284.     if(flushit) {
  285. dirflush = 0;
  286. winclr(main_w);
  287. wredraw(main_w, 1);
  288.     }
  289.     wcursor(main_w, CNORMAL);
  290.     /* select <a file|one or more files|a directory> for <upload|download> */
  291.     snprintf(file_title, sizeof(file_title), _("Select %s for %s"),
  292.       how_many? (how_many < 0? _("one or more files") : _("a file"))
  293.     : _("a directory"),
  294.       down_loading? _("download") : _("upload"));
  295.     wtitle(main_w, TMID, file_title);
  296.     if((new_dp_len = strlen(work_dir)) > dp_len) {
  297.       dp_len = new_dp_len;
  298.       snprintf(cwd_str_fmt, sizeof(cwd_str_fmt),
  299.        _("Directory: %%-%ds"), dp_len);
  300.     }
  301.     if (new_dp_len + (fmt_len = strlen(cwd_str_fmt)) > 75) {
  302.       snprintf(disp_dir, sizeof(disp_dir),
  303.        "...%s", work_dir + new_dp_len - 73 + fmt_len);
  304.       snprintf(cwd_str, sizeof(cwd_str), cwd_str_fmt, disp_dir);
  305.     }
  306.     else
  307.       snprintf(cwd_str, sizeof(cwd_str), cwd_str_fmt, work_dir);
  308.     wlocate(main_w, 0, 0);
  309.     wputs(main_w, cwd_str);
  310.     wlocate(dsub, initial_y, 0);
  311.     wputs(dsub, _(what));
  312.     wsetregion(main_w, 1, main_w->ys - FILE_MWTR);
  313.     main_w->doscroll = 0;
  314.     /* old dir to discard? */
  315.     if(o_dirdat != (GETSDIR_ENTRY *) NULL)
  316. free(o_dirdat);
  317.     /* get sorted directory */
  318.     if((nrents = getsdir(".", wc_str,
  319.       GETSDIR_PARNT|GETSDIR_NSORT|GETSDIR_DIRSF, 0, &dirdat, &longest)) < 0) {
  320. /* we really want to announce the error here!!! */
  321. wclose(main_w, 1);
  322. wclose(dsub, 1);
  323. free(dirdat);
  324. return(-1);
  325.     }
  326.     prdir(main_w, top, top, dirdat, longest);  
  327.     wlocate(main_w, initial_y, main_w->ys - FILE_MWTR);
  328.     wputs(main_w, _("( Escape to exit, Space to tag )"));
  329.     dhili(subm);
  330.     /* this really needs to go in dhili !!!*/
  331.     wlocate(main_w, 0, cur + FILE_MWTR - top);
  332.     if(flushit) {
  333. dirflush = 1;
  334. wredraw(dsub, 1);
  335.     }
  336.     return(0);
  337. }
  338. /*
  339.  * Goto a new directory
  340.  */
  341. static void
  342. goto_filedir(new_dir, absolut)
  343. char *new_dir;
  344. int absolut;
  345. {
  346.     if(strcmp(new_dir, "..") == 0) {
  347. if(strcmp(work_dir, "/")) {
  348.     char *sp = strrchr(work_dir, '/');
  349.     *sp = (char) 0;
  350.     if(strlen(work_dir) == 0)
  351. strcpy(work_dir, "/");
  352. }
  353. else {
  354.     file_tell(_("Can't back up!"));
  355.     return;
  356. }
  357.     }
  358.     else if(!absolut) {
  359. int new_len = strlen(work_dir) + 1; /* + '/' */
  360. if((new_len += strlen(new_dir) + 1) > min_len) {
  361.     min_len = new_len;
  362.     work_dir = set_work_dir(work_dir, min_len);
  363. }
  364. if(strcmp(work_dir, "/") != 0)
  365.     strcat(work_dir, "/");
  366. strcat(work_dir, new_dir);
  367.     }
  368.     else {
  369. int new_len = 1;
  370. if(*new_dir != '/')
  371.     new_len += strlen(homedir) + 1;
  372. new_len += strlen(new_dir);
  373. if(min_len < new_len)
  374.     min_len = new_len;
  375. work_dir = set_work_dir(work_dir, min_len);
  376. if(*new_dir == '/')
  377.     strncpy(work_dir, new_dir, min_len);
  378. else
  379.     snprintf(work_dir, min_len, "%s/%s", homedir, new_dir);
  380.     }
  381.     new_filedir(dirdat, 1);
  382. }
  383. /*
  384.  * Initialize the file directory.
  385.  */
  386. static int
  387. init_filedir()
  388. {
  389.     int x1, x2;
  390.     int retstat = -1;
  391.     dirflush = 0;
  392.     x1 = (COLS / 2) - 37;
  393.     x2 = (COLS / 2) + 37;
  394.     dsub = wopen(x1 - 1, LINES - 3, x2 + 1, LINES - 3, BNONE, 
  395. stdattr, mfcolor, mbcolor, 0, 0, 1);
  396.     main_w = wopen(x1, 2, x2, LINES - 6, BSINGLE, stdattr, mfcolor,
  397. mbcolor, 0, 0, 1);
  398.     if(ret_buf != NULL ||
  399.       (retstat = ((ret_buf = malloc(BUFSIZ)) == NULL)? -1 : 0) == 0) {
  400. retstat = new_filedir((GETSDIR_ENTRY *) NULL, 0);
  401. dirflush = 1;
  402. wredraw(dsub, 1);
  403.     }
  404.     return(retstat);
  405. }
  406. static int
  407. tag_untag(pat, tag)
  408. char *pat;
  409. int tag;
  410. {
  411.     GETSDIR_ENTRY *my_d = dirdat;
  412.     int indxr, cntr;
  413.     for(indxr = nrents, cntr = 0; indxr; --indxr, ++my_d)
  414. if(S_ISREG(my_d->mode) && wildmat(my_d->fname, pat)) {
  415.     if(tag) {
  416. my_d->cflags |= FL_TAG;
  417. ++cntr;
  418.     }
  419.     else if(my_d->cflags & FL_TAG) {
  420. my_d->cflags &= ~FL_TAG;
  421. ++cntr;
  422.     }
  423. }
  424.     return(cntr);
  425. }
  426. /*
  427.  * concatenate tagged files into a buffer
  428.  */
  429. static char *
  430. concat_list(d)
  431. GETSDIR_ENTRY *d;
  432. {
  433.     GETSDIR_ENTRY *my_d;
  434.     int indxr, len;
  435.     my_d = d;
  436.     for(indxr = nrents, len = 0; indxr; --indxr, ++my_d)
  437. if(my_d->cflags & FL_TAG)
  438.     len += strlen(my_d->fname) + 1;
  439.     if(len) {
  440. if(len > BUFSIZ) {
  441.   if((ret_buf = realloc(ret_buf, len)) == NULL) {
  442.       file_tell(_("Too many files tagged - buffer would overflow"));
  443.       return(NULL);
  444.   }
  445. }
  446.     
  447. *ret_buf = (char) 0;
  448. my_d = d;
  449. for(indxr = nrents; indxr; --indxr, ++my_d)
  450.     if(my_d->cflags & FL_TAG) {
  451. /* this could be *much* more efficient */
  452. strcat(ret_buf, my_d->fname);
  453. strcat(ret_buf, " ");
  454.     }
  455. ret_buf[strlen(ret_buf) - 1] = (char) 0;
  456. return(ret_buf);
  457.     }
  458.     return(NULL);
  459. }
  460. /*
  461.  * Draw the file directory.
  462.  *
  463.  *      howmany - How many files can be selected
  464.  *       0 = none (for directory selection only, as in "rz")
  465.  *       1 = one  (for single-file up-/down-loads, as in "rx")
  466.  *      -1 = any number (for multiple files, as in "sz")
  467.  *
  468.  *    downloading - Is this for download selection?
  469.  *       0 = no
  470.  *       1 = yes - when single file selected, see if it exists
  471.  */
  472. char *
  473. filedir(howmany, downloading)
  474. int howmany;
  475. int downloading;
  476. {
  477.     time_t click_time = (time_t) 0;
  478.     how_many = howmany;
  479.     down_loading = downloading;
  480.     init_filedir();
  481. again:
  482.     wlocate(main_w, 0, cur + FILE_MWTR - top);
  483.     if(first) {
  484. wredraw(main_w, 1);
  485. first = 0;
  486.     }
  487.     while(!quit) {
  488. d = getno(cur, dirdat);
  489. /*
  490. if(S_ISDIR(d->mode))
  491.     prone(main_w, top, top, d, longest, 0);
  492. */
  493. switch(c = wxgetch()) {
  494.     case K_UP:
  495.     case 'k':
  496. /*
  497. if(S_ISDIR(d->mode))
  498.     prone(main_w, top, top, d, longest, 1);
  499. */
  500. cur -= (cur > 0);
  501. break;
  502.     case K_DN:
  503.     case 'j':
  504. /*
  505. if(S_ISDIR(d->mode))
  506.     prone(main_w, top, top, d, longest, 1);
  507. */
  508. cur += (cur < nrents - 1);
  509. break;
  510.     case K_LT:
  511.     case 'h':
  512. subm--;
  513. if(subm < 0)
  514.     subm = SUBM_OKAY;
  515. break;
  516.     case K_RT:
  517.     case 'l':
  518. subm = (subm + 1) % 6;
  519. break;
  520.     case K_PGUP:
  521.     case '02': /* Control-B */
  522. pgud = 1;
  523. quit = 1;
  524. break;
  525.     case K_PGDN:
  526.     case '06': /* Control-F */
  527. pgud = 2;
  528. quit = 1;
  529. break;
  530.     case 'f':    /* Find. */
  531. subm = 1;
  532. quit = 1;
  533. break;
  534.     case ' ':    /* Tag if not directory */
  535. if(S_ISDIR(d->mode)) {
  536.     time_t this_time = time((time_t *) NULL);
  537.     if(this_time - click_time < 2) {
  538. GETSDIR_ENTRY *d2 = getno(cur, dirdat);
  539. goto_filedir(d2->fname, 0);
  540. click_time = (time_t) 0;
  541.     }
  542.     else
  543. click_time = this_time;
  544. }
  545. else {
  546.     if(how_many) {
  547. if((d->cflags ^= FL_TAG) & FL_TAG) {
  548.     if(tag_cnt && how_many == 1) {
  549. d->cflags &= ~FL_TAG;
  550. file_tell(_("Can select only one!"));
  551. break;
  552.     }
  553.     ++tag_cnt;
  554. }
  555. else
  556.     --tag_cnt;
  557. wlocate(main_w, 0, cur + FILE_MWTR - top);
  558. prone(main_w, top, top, d, longest, d->cflags & FL_TAG);
  559. wputc(main_w, 'n');
  560. cur += (cur < nrents - 1);
  561.     }
  562. }
  563. break;
  564.     case 'G':
  565.     case 'g':
  566. subm = 0;
  567. goto real_programmers_use_gotos;
  568. break;
  569.     case 'P':
  570.     case 'p':
  571. subm = 1;
  572. goto real_programmers_use_gotos;
  573. break;
  574.     case 'S':
  575.     case 's':
  576. subm = 2;
  577. goto real_programmers_use_gotos;
  578. break;
  579.     case 'T':
  580.     case 't':
  581. subm = 3;
  582. goto real_programmers_use_gotos;
  583. break;
  584.     case 'U':
  585.     case 'u':
  586. subm = 4;
  587. goto real_programmers_use_gotos;
  588. break;
  589.     case 'O':
  590.     case 'o':
  591. subm = SUBM_OKAY;
  592. real_programmers_use_gotos:
  593. c = 'n';
  594. quit = 1;
  595. break;
  596.     case '33':
  597.     case 'r':
  598.     case 'n':
  599. quit = 1;
  600. break;
  601.     default:
  602. break;
  603. }
  604. if(c != ' ')
  605.     click_time = (time_t) 0;
  606. if(cur < top) {
  607.     top--;
  608.     prdir(main_w, top, top, dirdat, longest);
  609. }
  610. if(cur - top > main_w->ys - (2 + FILE_MWTR)) {
  611.     top++;
  612.     prdir(main_w, top, top, dirdat, longest);
  613. }
  614. /*
  615. if(cur != ocur)
  616.     wlocate(main_w, 0, cur + FILE_MWTR - top);
  617.  */
  618. ocur = cur;
  619. dhili(subm);
  620. /* this really needs to go in dhili !!!*/
  621. wlocate(main_w, 0, cur + FILE_MWTR - top);
  622.     }
  623.     quit = 0;
  624.     /* ESC means quit */
  625.     if(c == '33') {
  626. wclose(main_w, 1);
  627. wclose(dsub, 1);
  628. free(dirdat);
  629. return(NULL);
  630.     }
  631.     /* Page up or down ? */
  632.     if(pgud == 1) { /* Page up */
  633. ocur = top;
  634. top -= main_w->ys - (1 + FILE_MWTR);
  635. if(top < 0)
  636.     top = 0;
  637. cur = top;
  638. pgud = 0;
  639. if(ocur != top)
  640.     prdir(main_w, top, cur, dirdat, longest);
  641. ocur = cur;
  642. goto again;
  643.     }
  644.     if(pgud == 2) { /* Page down */
  645. ocur = top;
  646. if(top < nrents - main_w->ys + (1 + FILE_MWTR)) {
  647.     top += main_w->ys - (1 + FILE_MWTR);
  648.     if(top > nrents - main_w->ys + (1 + FILE_MWTR)) {
  649. top = nrents - main_w->ys + (1 + FILE_MWTR);
  650.     }
  651.     cur = top;
  652. } else
  653.     cur = nrents - 1;
  654. pgud = 0;
  655. if(ocur != top)
  656.     prdir(main_w, top, cur, dirdat, longest);
  657. ocur = cur;
  658. goto again;
  659.     }
  660.     if(c =='r' || c == 'n') {
  661. switch(subm) {
  662.     case 0:
  663. /* Goto directory */
  664. {
  665.     char buf[128];
  666.     char *s;
  667.     strncpy(buf, down_loading? P_DOWNDIR : P_UPDIR,
  668. sizeof(buf) -1);
  669.     s = input(_("Goto directory:"), buf);
  670. /*     if(s == CNULL || *s == (char) 0) */
  671.     if(s == CNULL)
  672. break;
  673.     goto_filedir(buf, 1);
  674. }
  675. break;
  676.     case 1:
  677. /* Previous directory */
  678. goto_filedir(prev_dir, 1);
  679. break;
  680.     case 2:
  681. /* File (wildcard) spec */
  682. {
  683.     char *s = input(_("Filename pattern:"), wc_mem);
  684.     if(s == CNULL || *s == (char) 0)
  685. break;
  686.     strcpy(wc_str, wc_mem);
  687.     new_filedir(dirdat, 1);
  688.     wc_str[0] = (char) 0;
  689. }
  690. break;
  691.     case 3:
  692. /* Tag */
  693. if(how_many == 1)
  694.     file_tell(_("Can select only one!"));
  695. else if(how_many == -1) {
  696.     char tag_buf[128];
  697.     char *s;
  698.     strncpy(tag_buf, wc_mem, 128);
  699.     
  700.     s = input(_("Tag pattern:"), tag_buf);
  701.     if(s != CNULL && *s != (char) 0) {
  702. int newly_tagged;
  703. if((newly_tagged = tag_untag(tag_buf, 1)) == 0) {
  704.     file_tell(_("No file(s) tagged"));
  705.     goto tag_end;
  706. }
  707. tag_cnt += newly_tagged;
  708. prdir(main_w, top, top, dirdat, longest);  
  709.     }
  710. }
  711. tag_end:
  712. break;
  713.     case 4:
  714. /* Untag */
  715. {
  716.     char tag_buf[128];
  717.     char *s;
  718.     int untagged;
  719.     strncpy(tag_buf, wc_mem, 128);
  720.     
  721.     s = input(_("Untag pattern:"), tag_buf);
  722.     if(s == CNULL || *s == (char) 0)
  723. goto untag_end;
  724.     if((untagged = tag_untag(tag_buf, 0)) == 0) {
  725. file_tell(_("No file(s) untagged"));
  726. goto untag_end;
  727.     }
  728.     tag_cnt -= untagged;
  729.     prdir(main_w, top, top, dirdat, longest);  
  730. }
  731. untag_end:
  732. break;
  733.     case 5:
  734. {
  735.   /* Done */
  736.   char *ret_ptr = NULL; /* failsafe: assume failure */
  737.   if(how_many != 0 && !tag_cnt) {
  738.     while(1) {
  739.       s = input(_("No file selected - enter filename:"),
  740. ret_buf);
  741.       if(s != CNULL && *s != (char) 0) {
  742. int f_exist = access(ret_buf, F_OK);
  743. if(down_loading) {
  744.   if(f_exist != -1) {
  745.     /* ask 'em if they're *sure* */
  746.     char buf[BUFSIZ];
  747.     snprintf(buf, sizeof(buf), 
  748.     _("File: "%s" exists!. Over-write?"),
  749.     ret_buf);
  750.     if(ask(buf, d_yesno) == 0) {
  751.       ret_ptr = ret_buf;
  752.       break;
  753.     }
  754.   }
  755.   else {
  756.     ret_ptr = ret_buf;
  757.     break;
  758.   }
  759. }
  760. else {
  761.   if(f_exist == -1)
  762.     file_tell(_("no such file!"));
  763.   else {
  764.     ret_ptr = ret_buf;
  765.     break;
  766.   }
  767. }
  768.       }
  769.       else {
  770. /* maybe want to ask: "abort?", here */
  771. goto again;
  772.       }
  773.     }
  774.   }
  775.   else {
  776.     /* put 'em in a buffer for return */
  777.     if(how_many == 0) {
  778.       /* current working directory */
  779.       ret_ptr = work_dir;
  780.     }
  781.     else {
  782.       ret_ptr = concat_list(dirdat);
  783.     }
  784.   }
  785.   wclose(main_w, 1);
  786.   wclose(dsub, 1);
  787.   free(dirdat);
  788.   return(ret_ptr);
  789. }
  790. break;
  791.     default:
  792. /* should "beep", I guess (? shouldn't get here) */
  793. file_tell("BEEP!");
  794. break;
  795. } /* switch */
  796.     }
  797.     goto again;
  798. }