home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume2 / xbrowser / part01 / commands.c next >
Encoding:
C/C++ Source or Header  |  1989-01-03  |  18.5 KB  |  863 lines

  1. /* Systems Sciences Laboratory, Webster Research Center */
  2.  
  3. static char *PROGRAM_information[] =
  4. {
  5.     "Copyright (c) 1988 Xerox Corporation.  All rights reserved.",
  6.     "$Header$",
  7.     "$Locker$"
  8. }
  9. ;
  10.  
  11. /*
  12.  * Copyright protection claimed includes all forms and matters of copyrightable
  13.  * material and information now allowed by statutory or judicial lay or
  14.  * herinafter granted, including without limitation, material generated from
  15.  * the software programs which are displayed on the screen such as icons,
  16.  * screen display looks, etc.
  17.  */
  18.  
  19.  
  20. #include "xfilebrowser.h"
  21. #include <ctype.h>
  22. #include <sys/file.h>
  23.  
  24. extern char *getenv();
  25. extern char *re_comp();
  26.  
  27. typedef enum { JHSXEDIT, EMACS, VI, XEDIT, XMORE, ED_UNKNOWN } edittype;
  28. typedef enum { DELETE, MOVE, COPY } requesttype;
  29.  
  30. static DialogData dialogdata;
  31. static unsigned int cmdsize = 1024;
  32.  
  33.  
  34. DoQuit()
  35. {
  36.     XtUnmapWidget(toplevel);
  37.     XCloseDisplay(curdisplay);
  38.     exit(0);
  39. }
  40.  
  41. /* ARGSUSED */
  42. setup_pattern(source, pattern)
  43. char *source, *pattern;
  44. {
  45.     register char *p = source;
  46.     register char *q = pattern;
  47.     
  48.     *q = '^'; q++;
  49.     while (*p != '\0') {
  50.        if (*p == '.') { *q = '\\'; q++; *q = '.'; }
  51.        else if (*p == '$') *q = '.';
  52.        else if (*p == '*') { *q = '.'; q++; *q = '*'; }
  53.        else *q = *p; 
  54.  
  55.        q++; p++;
  56.     }
  57.     *q = '$'; q++; *q = '\0';
  58. }
  59.  
  60. /* ARGSUSED */
  61. DoList(w, client_data, call_data)
  62. Widget w;
  63. caddr_t client_data, call_data;
  64. {
  65.     int i;
  66.     char *error;
  67.     char tmppattern[64], curpattern[255];
  68.     XtTextPosition pos1, pos2;
  69.     short dir;
  70.     struct stat buf;
  71.  
  72.     switch ((int)call_data) {
  73.        case 2: dir = -1; break;
  74.        case 3: 
  75.         if (!check_option()) display_listoptions(w); 
  76.         return;
  77.  
  78.        case 0:
  79.        case 1: 
  80.        default: dir = (short)call_data; break;
  81.     }
  82.  
  83.     XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  84.     if (pos1 != pos2 && numfiles != 0 && 
  85.         ( (i = select_file(pos1, pos2)) != -1)) {
  86.        if (stat((*files[i]).d_name, &buf) == -1) {
  87.          disp_message("\nList: cannot check file stats");
  88.             return;
  89.         }
  90.         if (buf.st_mode & S_IFDIR) 
  91.             sprintf(curpattern, "%s/%s", (*files[i]).d_name, filepattern);
  92.         else {
  93.             disp_message(
  94.        "\nList: selected file %s is not a directory\nuse current pattern",
  95.                 (*files[i]).d_name);
  96.         if (! strcmp(filepattern, oldpattern)) return;
  97.             else strcpy(curpattern, filepattern);
  98.        }
  99.     }
  100.     else strcpy(curpattern, filepattern);
  101.  
  102.     if (strcmp(curpattern, oldpattern)) {
  103.         /* old pattern and new pattern differ */
  104.        if (get_dirpat(curpattern, curdirectory, oldpattern) == -1) {
  105.            disp_message("\nList: access to directory?");
  106.            return;
  107.        }
  108.     }
  109.     
  110.     setup_pattern(oldpattern, tmppattern);
  111.     if (error = re_comp(tmppattern)) {
  112.        disp_message("\nList: search pattern %s?", error);
  113.        return;
  114.     }
  115.  
  116.     clear_widget(grepwidget, grepsource);
  117.     clear_widget(listwidget, listsource);
  118.     free_direct(&files, &numfiles);
  119.     free_hitfiles();
  120.  
  121.     if (prepare_list(curdirectory, dir, &files, &numfiles, 
  122.             (char *)NULL) != -1) {
  123.        if (!(chdir(curdirectory))) {
  124.            strcpy(filepattern, oldpattern);
  125.            setup_dirlabel(curdirectory, oldpattern);
  126.        }
  127.        else disp_message("\nList: problems in changing to %s",
  128.              curdirectory);
  129.        display_files(0);
  130.     }
  131.     else clear_widget(listwidget, listsource);
  132.  
  133.     setup_iconname();
  134.  
  135.     return;
  136. }
  137.  
  138.  
  139. /***************************
  140. *     Edit Routines 
  141. ****************************/
  142.  
  143. /* ARGSUSED */
  144. edittype check_editor(s)
  145. char *s;
  146. {
  147.     char *p, *q;
  148.     int len;
  149.     edittype result;
  150.     
  151.     p = s; result = ED_UNKNOWN;
  152.     while ( p != NULL) {
  153.        if ( (q = index(p, ' ')) != NULL) len = q - p;
  154.        else len = strlen(p);
  155.  
  156.        if (! strncmp(p, "jhsxedit", len)) { result = JHSXEDIT; break; }
  157.        else if (! strncmp(p, "xedit", len)) { result = XEDIT; break; }
  158.        else if (! strncmp(p, "emacs", len)) { result = EMACS; break; }
  159.        else if (! strncmp(p, "vi", len)) { result = VI; break; }
  160.        else if (! strncmp(p, "xmore", len)) { result = XMORE; break; }
  161.  
  162.        if (q != NULL) {
  163.         q++;
  164.            while (*q == ' ') q++;
  165.            p = q;
  166.        }
  167.        else break;
  168.     }
  169.     
  170.     return result;
  171. }
  172.  
  173. /* ARGSUSED */
  174. invoke_editor(file, toline, edit)
  175. char *file;
  176. int toline;
  177. Boolean edit;
  178. {
  179.     int cc;
  180.     char command[255];
  181.     char *editor = NULL, *curviewer;
  182.     struct stat buf;
  183.     edittype edit_view;
  184.     static char xviewer[] = "xmore";
  185.     static char xeditor[] = "xedit";
  186.     
  187.     if (stat(file, &buf) == -1) {
  188.         disp_message("\nEdit: cannot check file stats");
  189.         return;
  190.      }
  191.  
  192.      if ( (buf.st_mode & S_IFMT) == S_IFREG ) {
  193.        if (!edit) {
  194.         edit_view = XMORE;
  195.         curviewer = &xviewer[0];
  196.        }
  197.        else {
  198.             if ( (editor = getenv("XEDITOR")) != NULL) {
  199.            edit_view = check_editor(editor);
  200.            curviewer = editor;
  201.         }
  202.         else {
  203.            edit_view = XEDIT;
  204.            curviewer = &xeditor[0];
  205.         }
  206.        }
  207.  
  208.           if (toline != 0) {
  209.             switch(edit_view) {
  210.                case JHSXEDIT:
  211.                case EMACS:
  212.                case VI:
  213.                    sprintf(command, "%s -display %s +%d %s&", 
  214.                curviewer, DisplayString(curdisplay), toline, file);
  215.                    break;
  216.                default:
  217.                    sprintf(command, "%s -display %s %s&",
  218.                           curviewer, DisplayString(curdisplay), file);
  219.                    break;
  220.         }
  221.         }
  222.        else sprintf(command, "%s -display %s %s&", 
  223.                 curviewer, DisplayString(curdisplay), file);
  224.        cc = system(command);
  225.     }
  226.     else disp_message("\nEdit: %s not regular file!", file);    
  227. }
  228.  
  229. DoEdit(w, client_data, call_data)
  230. Widget w;
  231. caddr_t client_data, call_data;
  232. {
  233.     XtTextPosition pos1, pos2;
  234.     int i;
  235.  
  236.     if ( (int)call_data == 3 ) return;
  237.     XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  238.     if (pos1 == pos2 || numfiles == 0) {
  239.         disp_message("\nEdit: no file selected");
  240.         return;
  241.      }
  242.  
  243.     if ( (i = select_file(pos1, pos2)) == -1) {
  244.         disp_message("\nEdit: file selection?");
  245.         return;
  246.      }
  247.  
  248.     switch ( (int)call_data ) {
  249.     case 1:    invoke_editor(files[i]->d_name, 0, False); break;
  250.     case 2:    invoke_editor(files[i]->d_name, 0, True); break;
  251.     }
  252.  
  253.     return;
  254. }
  255.  
  256.  
  257. /***************************
  258. *     Grep/GrepEdit Routines 
  259. ****************************/
  260.  
  261. DoGrepEdit(w, client_data, call_data)
  262. Widget w;
  263. caddr_t client_data, call_data;
  264. {
  265.     XtTextPosition pos1, pos2;
  266.     int i, linenr;
  267.  
  268.     if ( (int)call_data == 3 ) return;
  269.  
  270.     XtTextGetSelectionPos(grepwidget, &pos1, &pos2);
  271.     if (pos1 == pos2 || numhitfiles == 0) {
  272.         disp_message("\nEdit: no file selected");
  273.         return;
  274.      }
  275.  
  276.     if ( (i = select_searchfile(pos1, pos2, &linenr)) == -1) {
  277.         disp_message("\nEdit: file selection?");
  278.         return;
  279.      }
  280.     switch ( (int)call_data ) {
  281.     case 1:    invoke_editor(hitfiles[i]->name, linenr, False); break;
  282.     case 2:    invoke_editor(hitfiles[i]->name, linenr, True); break;
  283.     }
  284.  
  285.     return;
  286. }
  287.  
  288.  
  289. DoGrep(w, client_data, call_data)
  290. Widget w;
  291. caddr_t client_data, call_data;
  292. {
  293.     XtTextPosition pos1, pos2, fstart, fend;
  294.     Boolean stopwhenfound = False;
  295.  
  296.     switch ((int)call_data) {
  297.        case 3: 
  298.         if (!check_search()) display_searchoptions(w); 
  299.         return;
  300.  
  301.        case 2:    stopwhenfound = True; break;
  302.        case 1:    break;
  303.        default:    return;
  304.     }
  305.  
  306.     if (numfiles == 0) {
  307.        disp_message("\nGrep: no files listed");
  308.        return;
  309.     }
  310.     
  311.     if (strlen(searchpattern) == 0) {
  312.        disp_message("\nGrep: search pattern?");
  313.        return;
  314.     }
  315.     if (index(searchpattern, '\n') != NULL) {
  316.        disp_message("\nGrep: search pattern contains newline");
  317.        return;
  318.     }
  319.  
  320.     clear_widget(grepwidget, grepsource);
  321.     free_hitfiles();
  322.  
  323.     XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  324.     if (pos1 == pos2 ||
  325.         select_files(pos1, pos2, &fstart, &fend) == -1) 
  326.        { fstart = 0; fend = numfiles -1; }
  327.  
  328.     examine_files(fstart, fend, stopwhenfound);
  329. }
  330.  
  331.  
  332. /***************************
  333. *     Shell Routines 
  334. ****************************/
  335.  
  336. /* ARGSUSED */
  337. int execute_cmdline(command, saveout, savediag)
  338. char *command;
  339. Boolean saveout, savediag;
  340. {
  341.     int cc, i;
  342.     int cmdindex = 0;
  343.     struct stat statbuf;
  344.     FILE *fin;
  345.     char tmpfile[16];
  346.     char buf[128];
  347.     char *cmd = command;
  348.  
  349.     if (saveout || savediag) {
  350.        cmdindex = strlen(cmd);
  351.        sprintf(tmpfile, "/tmp/xbXXXXXX");
  352.        if (mktemp(tmpfile) == NULL) {
  353.            disp_message("\ncannot create log file");
  354.            return(-1);
  355.        }
  356.  
  357.        strcat(cmd, (savediag) ? " 2>" : " 1>");
  358.        strcat(cmd, tmpfile);
  359.        if (savediag && saveout) strcat(cmd, " 1>&2");
  360.     }
  361.     else *tmpfile = '\0';
  362.  
  363.     cc = system(cmd);
  364.     if (cc != 0)
  365.        disp_message(
  366.         "\nexit status is %d\ncheck command or targetfile",
  367.          cc);
  368.  
  369.     if (*tmpfile != '\0' && stat(tmpfile, &statbuf) == 0) {
  370.           if (statbuf.st_size > 0) {
  371.              if (statbuf.st_size < 127) {
  372.                  fin = fopen(tmpfile, "r");
  373.                  i = fread(buf, 1, 127, fin);
  374.                  fclose(fin);
  375.                  buf[i] = '\0';
  376.                  disp_message("\n%s", buf);
  377.           }
  378.           else {
  379.               command[cmdindex] = '\0'; 
  380.             /* delete tmpfile name from command */
  381.               log_popup(command, tmpfile);
  382.               }
  383.        }
  384.        unlink(tmpfile);
  385.     }
  386.     
  387.     XtTextUnsetSelection(listwidget);
  388.     return(cc);
  389. }
  390.  
  391.  
  392. shellcancel(clientdata)
  393. DialogData *clientdata;
  394. {
  395.     return;
  396. }
  397.  
  398. /* ARGSUSED */
  399. shellok(clientdata)
  400. DialogData *clientdata;
  401. {
  402.     char *answer = clientdata->answer;
  403.     char *tilde, *expand, *begquote, *endquote;
  404.  
  405.     if ( (tilde = index(answer, '~')) != NULL) {
  406.         /* check if tilde is between single quotes; then do not
  407.         expand tilde */
  408.        if ( ((begquote = index(answer, '\'')) == NULL) ||
  409.            ((endquote = index(begquote+1, '\'')) == NULL) ||
  410.            (tilde < begquote || tilde > endquote)) {
  411.  
  412.            if ( (expand = expand_tilde(tilde)) == NULL) {
  413.               disp_message("\ncannot expand ~");
  414.               return;
  415.         }
  416.            strcpy(tilde, expand);    /* replaces tilde by the actual
  417.                 path name */
  418.            XtFree(expand);
  419.        }
  420.     }
  421.  
  422.     execute_cmdline(answer, clientdata->out, clientdata->diag);
  423.     return;
  424. }
  425.  
  426. /* ARGSUSED */
  427. DoShell(w, client_data, call_data)
  428. Widget w;
  429. caddr_t client_data, call_data;
  430. {
  431.     char command[64];
  432.     char label[32];
  433.     char *defvalue;
  434.     XtTextPosition pos1, pos2, fstart, fend;
  435.     int i, len = 0;
  436.  
  437.     switch ((int)call_data) {
  438.        case 2:     sprintf(command, "xterm -display %s &",
  439.                    DisplayString(curdisplay));
  440.             system(command);
  441.             break;
  442.        case 1: 
  443.             if (check_prompt() == -1) return;
  444.                 /* there is already a prompt window */    
  445.             XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  446.             if (pos1 != pos2 && 
  447.                select_files(pos1, pos2, &fstart, &fend) != -1) {
  448.                if ( (fend - fstart + 1) == numfiles) {
  449.                 defvalue = XtMalloc(255);
  450.                 strcpy(defvalue, oldpattern);
  451.                }
  452.                else {
  453.                       for (i = fstart; i <= fend; i++)
  454.                          len += files[i]->d_namlen;
  455.                    defvalue = XtCalloc(len + (fend - fstart) + 64);
  456.                    for (i = fstart; i <= fend; i++) {
  457.                       strcat(defvalue, " ");
  458.                       strcat(defvalue, files[i]->d_name);
  459.                    }
  460.                }
  461.             }
  462.             else defvalue = XtCalloc(255, 1);
  463.  
  464.             dialogdata.w = w;
  465.             dialogdata.start = 0;
  466.             dialogdata.end = 0;
  467.             dialogdata.current = 0;
  468.             dialogdata.yes = shellok;
  469.             dialogdata.no = NULL;
  470.             dialogdata.cancel = shellcancel;
  471.             sprintf(label, "which shell command to execute?");
  472.             create_toggleprompt(&dialogdata, label, defvalue);
  473.             XtFree(defvalue);
  474.             break;
  475.        case 3: 
  476.        default:    break;
  477.     }
  478.     return;
  479. }
  480.  
  481.  
  482.  
  483. /***************************
  484. *     Copy Routines 
  485. ****************************/
  486.  
  487. /* ARGSUSED */
  488. copyok(clientdata)
  489. DialogData *clientdata;
  490. {
  491.     int fstart = clientdata->start;
  492.     int fend = clientdata->end;
  493.     int i;
  494.     char *s = clientdata->answer;
  495.     char *name;
  496.  
  497.     strcpy(cmdline, "cp ");
  498.     for (i = fstart; i <= fend; i++) {
  499.        strcat(cmdline, "'");
  500.        strcat(cmdline, files[i]->d_name);
  501.        strcat(cmdline, "' ");
  502.     }
  503.     if (*s == '~') {
  504.        if ( (name = expand_tilde(s)) == NULL) {
  505.            disp_message("\nCopy: cannot expand target name");
  506.            return;
  507.        }
  508.     }
  509.     else name = s;
  510.     strcat(cmdline, name);
  511.  
  512.     if (execute_cmdline(cmdline, FALSE, TRUE) == 0) {
  513.        if (fstart == fend) 
  514.         DoList(clientdata->w, (caddr_t)clientdata, (caddr_t)0);
  515.  
  516.         /* copied file may be in the same directory; if values
  517.         are different assume files were copied into different
  518.         directory */
  519.     }
  520.     return;
  521. }
  522.  
  523. copycancel(clientdata)
  524. DialogData *clientdata;
  525. {
  526.     return;
  527. }
  528.  
  529. /* ARGSUSED */
  530. DoCopy(w, client_data, call_data)
  531. Widget w;
  532. caddr_t client_data, call_data;
  533. {
  534.     XtTextPosition pos1, pos2, fstart, fend;
  535.     char label[32];
  536.     char defvalue[255];
  537.  
  538.     if (check_prompt() == -1) return;
  539.                 /* there is already a prompt window */
  540.     if (numfiles == 0) {
  541.        disp_message("\nCopy: no files listed");
  542.        return;
  543.     }
  544.  
  545.     XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  546.     if (pos1 == pos2 || select_files(pos1, pos2, &fstart, &fend) == -1) {
  547.        disp_message("\nCopy: no file selected");
  548.        return;
  549.     }
  550.  
  551.     dialogdata.w = w;
  552.     dialogdata.start = fstart;
  553.     dialogdata.end = fend;
  554.     dialogdata.current = fend;
  555.     dialogdata.yes = copyok;
  556.     dialogdata.no = NULL;
  557.     dialogdata.cancel = copycancel;
  558.  
  559.     if (fstart == fend) {
  560.        sprintf(label, "copy selected file to?");
  561.        sprintf(defvalue, "%s", files[fstart]->d_name);
  562.     }
  563.     else {
  564.        sprintf(label, "copy selected files to directory?");
  565.        defvalue[0] = '\0';
  566.     }
  567.     create_prompt(&dialogdata, label, defvalue);
  568.     return;
  569. }
  570.  
  571.  
  572. /***************************
  573. *     Move Routines 
  574. ****************************/
  575.  
  576. /* ARGSUSED */
  577. moveok(clientdata)
  578. DialogData *clientdata;
  579. {
  580.     int fstart = clientdata->start;
  581.     int fend = clientdata->end;
  582.     int i;
  583.     char *s = clientdata->answer;
  584.     char *name;
  585.  
  586.     strcpy(cmdline, "mv ");
  587.     for (i = fstart; i <= fend; i++) {
  588.        strcat(cmdline, "'");
  589.        strcat(cmdline, files[i]->d_name);
  590.        strcat(cmdline, "' ");
  591.     }
  592.     if (*s == '~') {
  593.        if ( (name = expand_tilde(s)) == NULL) {
  594.            disp_message("\nMove: cannot expand target name");
  595.            return;
  596.        }
  597.     }
  598.     else name = s;
  599.     strcat(cmdline, name);
  600.  
  601.     if (execute_cmdline(cmdline, FALSE, TRUE) == 0) {
  602.        DoList(clientdata->w, (caddr_t)clientdata, (caddr_t)0);
  603.     }
  604.     return;
  605. }
  606.  
  607. movecancel(clientdata)
  608. DialogData *clientdata;
  609. {
  610.     return;
  611. }
  612.  
  613. /* ARGSUSED */
  614. DoRename(w, client_data, call_data)
  615. Widget w;
  616. caddr_t client_data, call_data;
  617. {
  618.     XtTextPosition pos1, pos2, fstart, fend;
  619.     char label[32];
  620.     char defvalue[255];
  621.  
  622.     if (check_prompt() == -1) return;
  623.                 /* there is already a prompt window */
  624.     if (numfiles == 0) {
  625.        disp_message("\nMove: no files listed");
  626.        return;
  627.     }
  628.  
  629.     XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  630.     if (pos1 == pos2 || select_files(pos1, pos2, &fstart, &fend) == -1) {
  631.        disp_message("\nMove: no file selected");
  632.        return;
  633.     }
  634.  
  635.     dialogdata.w = w;
  636.     dialogdata.start = fstart;
  637.     dialogdata.end = fend;
  638.     dialogdata.current = fend;
  639.     dialogdata.yes = moveok;
  640.     dialogdata.no = NULL;
  641.     dialogdata.cancel = movecancel;
  642.  
  643.     if (fstart == fend) {
  644.        sprintf(label, "move selected file to?");
  645.        sprintf(defvalue, "%s", files[fstart]->d_name);
  646.     }
  647.     else {
  648.        sprintf(label, "move selected files to directory?");
  649.        defvalue[0] = '\0';
  650.     }
  651.  
  652.     create_prompt(&dialogdata, label, defvalue);
  653.     return;
  654. }
  655.  
  656.  
  657. /***************************
  658. *     Delete Routines 
  659. ****************************/
  660.  
  661. /* ARGSUSED */
  662. update_list(fstart, fend, sort)
  663. int fstart, fend;
  664. short sort;
  665. {
  666.     int i;
  667.     int next = fstart;
  668.     int position = files[fstart]->d_pos1;
  669.  
  670.     for (i = fstart; i <= fend; i++) {
  671.        if (files[i]->d_marked == 0) {
  672.            if (next < i) files[next] = files[i];
  673.            next++;
  674.        }
  675.        else if (! access(files[i]->d_name, F_OK) ) {
  676.         disp_message("\nfile %s not removed", files[i]->d_name);
  677.         if (next < i) files[next] = files[i];
  678.            next++;
  679.        }
  680.        else XtFree(files[i]);
  681.     }
  682.     
  683.     if (next == i) return; /* no files were deleted */
  684.  
  685.     for (i = fend + 1; i < numfiles; i++) 
  686.        files[next++] = files[i];
  687.     numfiles = next;
  688.     if (sort) ;/* then sort files again */
  689.     display_files(position);
  690. }
  691.  
  692. /* ARGSUSED */
  693. confirm(data, cur, op)
  694. DialogData *data;
  695. int cur;
  696. requesttype op;
  697. {
  698.     struct stat buf;
  699.     char label[255];
  700.  
  701.     data->current = cur;
  702.     switch (op) {
  703.     case DELETE:
  704.         if (files[cur]->d_type == 'd')
  705.             sprintf(label, "delete directory %s and its content?",
  706.                    files[cur]->d_name);
  707.         else if (files[cur]->d_type == 'l') {
  708.            if (stat(files[cur]->d_name, &buf) == -1) {
  709.             sprintf(label, 
  710.                 "cannot check status of %s; delete anyway?",
  711.                    files[cur]->d_name);
  712.            }
  713.         }
  714.         else     sprintf(label, "delete file %s",
  715.                    files[cur]->d_name);
  716.         break;
  717.  
  718.     default: return;
  719.     }
  720.     create_confirm(data, label);
  721. }
  722.  
  723.  
  724. /* ARGSUSED */
  725. deleteyes(clientdata)
  726. DialogData *clientdata;
  727. {
  728.     int cur = clientdata->current;
  729.     struct afile *fp;
  730.  
  731.     fp = files[cur];
  732.     if ( (strlen(cmdline) + strlen(fp->d_name) + 1) >= cmdsize) {
  733.        cmdsize += 1024;
  734.        XtRealloc(cmdsize, cmdsize);
  735.     }
  736.     strcat(cmdline, " '");
  737.     strcat(cmdline, fp->d_name);
  738.     strcat(cmdline, "'");
  739.     fp->d_marked = 1;    /* file is marked for deletion */
  740.  
  741.     if (cur < clientdata->end) {
  742.        confirm(clientdata, cur+1, DELETE);
  743.     }
  744.     else {
  745.        if (execute_cmdline(cmdline, FALSE, TRUE) == 0)
  746.            update_list(clientdata->start, clientdata->end, 0);
  747.     }
  748.     return;
  749. }
  750.  
  751. /* ARGSUSED */
  752. deleteno(clientdata)
  753. DialogData *clientdata;
  754. {
  755.     int cur = clientdata->current;
  756.     short found = 0;
  757.     int i;
  758.  
  759.     if (cur < clientdata->end) {
  760.        confirm(clientdata, cur+1, DELETE);
  761.     }
  762.     else {
  763.         /* check if there is any file to delete */
  764.        for (i = clientdata->start; i <= clientdata->end; i++) {
  765.            if (files[i]->d_marked != 0) {
  766.               found = 1;
  767.               break;
  768.         }
  769.        }
  770.        if (!found) return;
  771.        if (execute_cmdline(cmdline, FALSE, TRUE) == 0)
  772.            update_list(clientdata->start, clientdata->end, 0);
  773.     }
  774.  
  775.     return;
  776. }
  777.  
  778. /* ARGSUSED */
  779. deletecancel(clientdata)
  780. DialogData *clientdata;
  781. {
  782.     int i;
  783.  
  784.     for (i = clientdata->start; i <= clientdata->end; i++) 
  785.        files[i]->d_marked = 0;
  786.     return;
  787. }
  788.  
  789.  
  790. /* ARGSUSED */
  791. DoDelete(w, client_data, call_data)
  792. Widget w;
  793. caddr_t client_data, call_data;
  794. {
  795.     XtTextPosition pos1, pos2, fstart, fend;
  796.  
  797.     if (check_confirm() == -1) return;
  798.                 /* there is already a prompt window */
  799.     if (numfiles == 0) {
  800.        disp_message("\nDelete: no files listed");
  801.        return;
  802.     }
  803.  
  804.     XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  805.     if (pos1 == pos2 || select_files(pos1, pos2, &fstart, &fend) == -1) {
  806.        disp_message("\nDelete: no file selected");
  807.        return;
  808.     }
  809.  
  810.     dialogdata.w = w;
  811.     dialogdata.yes = deleteyes;
  812.     dialogdata.no = deleteno;
  813.     dialogdata.cancel = deletecancel;
  814.     dialogdata.start = fstart;
  815.     dialogdata.end = fend;
  816.     strcpy(cmdline, "rm -rf");
  817.  
  818.     confirm(&dialogdata, fstart, DELETE);
  819.     return;
  820. }
  821.  
  822.  
  823. /*******************************
  824. *     Parent Directory Routines 
  825. ********************************/
  826.  
  827. DoParent(w, client_data, call_data)
  828. Widget w;
  829. caddr_t client_data, call_data;
  830. {
  831.     char *p;
  832.  
  833.     if ( (int)call_data == 3) return;
  834.             /* right button was pressed; no action is
  835.             taken */
  836.  
  837.     if ( (p = rindex(curdirectory, '/')) == NULL)
  838.        disp_message("\nParent: cannot select parent directory");
  839.     else {
  840.        if ( (p - curdirectory) == 0) p[1] = '\0'; 
  841.             /* already at the beginning */
  842.        else p[0] = '\0';
  843.        if (!(chdir(curdirectory))) 
  844.         setup_dirlabel(curdirectory, filepattern);
  845.        else disp_message("\nParent: problems in changing to %s",
  846.             curdirectory);
  847.     }
  848.  
  849.     XtTextUnsetSelection(listwidget);
  850.  
  851.     switch ((int)call_data) {
  852.        case 2: 
  853.         clear_widget(listwidget, listsource); break;
  854.  
  855.        case 1: 
  856.        default: 
  857.         XtTextUnsetSelection(listwidget);
  858.         DoList(w, client_data, (caddr_t)0); break;
  859.     }
  860.  
  861.     return;
  862. }
  863.