home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume21 / pan / part01 / pan3.0 / control.c next >
Encoding:
C/C++ Source or Header  |  1993-11-08  |  24.0 KB  |  881 lines

  1. /*
  2. Post A Note V3.0
  3. Copyright (c) 1993, Jeffrey W. Bailey
  4. All rights reserved.
  5.  
  6. Permission is granted to distribute this program in exact, complete
  7. source form, which includes this copyright notice, as long as no fee
  8. other than media and distribution cost is charged.
  9.  
  10. This program may not be used in whole, or in part, in any other manner
  11. without prior written permission from the author.
  12.  
  13. This program may not be distributed in modified form without prior
  14. written permission from the author.  In other words, patches may be
  15. distributed, but modified source may not be distributed.
  16.  
  17. If there are any questions, comments or suggestions, the author may be
  18. contacted at:
  19.  
  20.     jeff@rd1.interlan.com
  21.  
  22.     or
  23.  
  24.     Jeffrey Bailey
  25.     Racal-Datacom, Inc.
  26.     Mail Stop E-110
  27.     1601 N. Harrison Parkway
  28.     Sunrise, FL  33323-2899
  29. */
  30.  
  31. #include "pan.h"
  32.  
  33. extern int errno;
  34. extern char *sys_errlist[];
  35.  
  36. struct Commands
  37.     {
  38.     char *Name;
  39.     int  (*Routine)();
  40.     };
  41.  
  42. int cmd_debug(), cmd_expose(), cmd_hide(), cmd_movenote(), cmd_newfolder();
  43. int cmd_newnote(), cmd_printnote(), cmd_quit(), cmd_rename(), cmd_veil();
  44.  
  45. static struct Commands cmds[] = {
  46.     {"debug",     cmd_debug},
  47.     {"expose",    cmd_expose},
  48.     {"hide",      cmd_hide},
  49.     {"move",      cmd_movenote},
  50.     {"newfolder", cmd_newfolder},
  51.     {"newnote",   cmd_newnote},
  52.     {"print",     cmd_printnote},
  53.     {"quit",      cmd_quit},
  54.     {"rename",    cmd_rename},
  55.     {"veil",      cmd_veil},
  56.     {NULL,        NULL}
  57. };
  58.  
  59. FILE *errfp;
  60.  
  61. static char ctrllck[MAXBUFLEN];
  62. static char ctrlnam[MAXBUFLEN];
  63. static char errlnam[MAXBUFLEN];
  64.  
  65. Notify_value check_ctl_file(client, which)
  66.     Notify_client client;
  67.     int  which;
  68.     {
  69.     int  fd;
  70.     struct stat mystat;
  71.  
  72.     sprintf(ctrllck, "%s/%s", note_dir, CTRLLCK);
  73.     if(stat(ctrllck, &mystat) == 0)
  74.         return(NOTIFY_DONE); /* control file is locked */
  75.  
  76.     sprintf(ctrlnam, "%s/%s", note_dir, CTRLNAM);
  77.     if(stat(ctrlnam, &mystat) < 0)
  78.         return(NOTIFY_DONE); /* control file doesn't exit */
  79.  
  80.     if((fd = open(ctrllck, O_CREAT|O_RDWR|O_EXCL, 0644) < 0))
  81.         return(NOTIFY_DONE); /* Couldn't acquire lock */
  82.     (void)close(fd);
  83.  
  84.     if(logging)
  85.         sprintf(errlnam, "%s/%s", note_dir, ERRLNAM);
  86.     else
  87.         strcpy(errlnam, "/dev/null");
  88.  
  89.     if((errfp = fopen(errlnam, "a")) == NULL)
  90.         {
  91.         (void) unlink(ctrllck);
  92.         fprintf(stderr, "%s:  Couldn't open %s for append\n", myname, errlnam);
  93.         return(NOTIFY_DONE);
  94.         }
  95.  
  96.     dispatch(ctrlnam);
  97.  
  98.     (void) fclose(errfp);
  99.     (void) unlink(ctrlnam);
  100.     (void) unlink(ctrllck);
  101.     return(NOTIFY_DONE);
  102.     }
  103.  
  104. dispatch(name)
  105.     char *name;
  106.     {
  107.     FILE *fp;
  108.     struct ps_component *lp;
  109.     int  i, found;
  110.     char buf[MAXBUFLEN];
  111.  
  112.     fp = fopen(name, "r");
  113.     if(fp == NULL)
  114.         {
  115.         fprintf(errfp, "%s:  Couldn't open %s:  %s\n", myname, name,
  116.                 sys_errlist[errno]);
  117.         return;
  118.         }
  119.  
  120.     while(fgets(buf, sizeof(buf), fp) != NULL)
  121.         {
  122.         trim(buf); /* skip comments & blank lines */
  123.         if(*buf == '#' || *buf == 0) continue;
  124.  
  125.         lp = parse_string(buf, " \t\n", 1, 1, 1);
  126.         if(lp == NULL) continue;
  127.  
  128.         for(i = 0, found = 0; cmds[i].Name != NULL; i++)
  129.             {
  130.             if(strcmp(lp->ps_text, cmds[i].Name) == 0)
  131.                 {
  132.                 fprintf(errfp, "%s:  **** executing {%s}\n", myname, buf);
  133.                 found = 1;
  134.                 (*cmds[i].Routine)(lp->ps_next);
  135.                 break;
  136.                 }
  137.             }
  138.         free_ps_list(lp);
  139.         if(!found)
  140.             {
  141.             fprintf(errfp, "%s:  Unrecognized command:  %s\n", myname, buf);
  142.             }
  143.         }
  144.  
  145.     (void) fclose(fp);
  146.     }
  147.  
  148. cmd_debug(lp)
  149.     struct ps_component *lp;
  150.     {
  151.     if(debug_on) fprintf(stderr, "cmd_debug\n");
  152.     if(lp == NULL ||
  153.        (strcmp(lp->ps_text, "on") != 0 && strcmp(lp->ps_text, "off") != 0))
  154.         {
  155.         fprintf(errfp, "%s:  debug command requires \"on|off\" parameter\n",
  156.             myname);
  157.         return;
  158.         }
  159.     if(strcmp(lp->ps_text, "on") == 0)
  160.         {
  161.         debug_on = 1;
  162.         }
  163.     else
  164.         {
  165.         debug_on = 0;
  166.         }
  167.     }
  168.  
  169. cmd_expose(lp)
  170.     struct ps_component *lp;
  171.     {
  172.     int  count;
  173.     int  res;
  174.     struct Note **npp;
  175.     struct LLM_root root;
  176.     char title[MAXBUFLEN];
  177.     int  gottitle;
  178.     int  lwindowmax;
  179.  
  180.     if(debug_on) fprintf(stderr, "cmd_expose\n");
  181.     lwindowmax = windowmax;
  182.     gottitle = 0;
  183.     while(lp != NULL)
  184.         {
  185.         if(lp->ps_next == NULL) /* go by two's, so we need another param */
  186.             {
  187.             fprintf(errfp, "%s:  Incorrect parameters for expose\n",
  188.                 myname);
  189.             return;
  190.             }
  191.         if(strcmp(lp->ps_text, "title") == 0)
  192.             {
  193.             lp = lp->ps_next;
  194.             strcpy(title, lp->ps_text);
  195.             gottitle = 1;
  196.             lp = lp->ps_next;
  197.             }
  198.         else if(strcmp(lp->ps_text, "windowmax") == 0)
  199.             {
  200.             lp = lp->ps_next;
  201.             lwindowmax = atoi(lp->ps_text);
  202.             lp = lp->ps_next;
  203.             }
  204.         else
  205.             {
  206.             fprintf(errfp, "%s:  Incorrect parameter {%s} for expose\n",
  207.                 myname, lp->ps_text);
  208.             return;
  209.             }
  210.         }
  211.     if(!gottitle)
  212.         {
  213.         fprintf(errfp, "%s:  Missing title for expose\n",
  214.             myname);
  215.         return;
  216.         }
  217.     res = w_matchingnotes(&root, title, 1);
  218.     switch(res)
  219.         {
  220.         case  -1 :
  221.             fprintf(errfp, "%s:  Invalid RE for expose command {%s}\n",
  222.                 myname, title);
  223.             return;
  224.             break;
  225.         case  -2 :
  226.             fprintf(errfp, "%s:  Memory allocation failure during expose\n",
  227.                 myname);
  228.             LLM_free(&root);
  229.             return;
  230.             break;
  231.         }
  232.     count = 0;
  233.     npp = (struct Note **) LLM_first(&root);
  234.     if(npp == NULL)
  235.         {
  236.         fprintf(errfp, "%s:  No matches found to expose for RE {%s}\n",
  237.             myname, title);
  238.         }
  239.     while(npp != NULL && (lwindowmax == -1 || count < lwindowmax))
  240.         {
  241.         count++;
  242.         w_exposenote(*npp, ERRINLOG);
  243.         npp = (struct Note **) LLM_next(&root);
  244.         }
  245.     LLM_free(&root);
  246.  
  247.     if(npp != NULL && count == lwindowmax)
  248.         fprintf(errfp, "%s:  expose halted at windowmax setting of %d\n",
  249.                   myname, count);
  250.     if(count)
  251.         fprintf(errfp, "%s:  exposed %d notes for RE {%s}\n",
  252.                   myname, count, title);
  253.     }
  254.  
  255. cmd_hide(lp)
  256.     struct ps_component *lp;
  257.     {
  258.     int  count;
  259.     int  res;
  260.     struct Note **npp;
  261.     struct LLM_root root;
  262.  
  263.     if(debug_on) fprintf(stderr, "cmd_hide\n");
  264.     if(lp == NULL || lp->ps_next == NULL)
  265.         {
  266.         fprintf(errfp, "%s:  hide command requires title RE parameter\n",
  267.             myname);
  268.         return;
  269.         }
  270.     if(debug_on)
  271.         fprintf(stderr, "hide {%s} {%s}\n", lp->ps_text,
  272.             lp->ps_next->ps_text);
  273.     if(strcmp(lp->ps_text, "title") != 0)
  274.         {
  275.         fprintf(errfp, "%s:  hide command requires title keyword\n",
  276.             myname);
  277.         return;
  278.         }
  279.     lp = lp->ps_next;
  280.     /*
  281.         This is slightly different than for expose - we will probably get
  282.         matches for notes that are already hidden because of the way
  283.         w_matchingnotes works.  It knows how to a) find all non-visible notes,
  284.         and b) all notes.
  285.     */
  286.     res = w_matchingnotes(&root, lp->ps_text, 0);
  287.     switch(res)
  288.         {
  289.         case  -1 :
  290.             fprintf(errfp, "%s:  Invalid RE for hide command {%s}\n",
  291.                 myname, lp->ps_text);
  292.             return;
  293.             break;
  294.         case  -2 :
  295.             fprintf(errfp, "%s:  Memory allocation failure during hide\n",
  296.                 myname);
  297.             LLM_free(&root);
  298.             return;
  299.             break;
  300.         }
  301.     count = 0;
  302.     npp = (struct Note **) LLM_first(&root);
  303.     if(npp == NULL)
  304.         {
  305.         fprintf(errfp, "%s:  No matches found to hide for RE {%s}\n",
  306.             myname, lp->ps_text);
  307.         }
  308.     while(npp != NULL)
  309.         {
  310.         /*
  311.             Make sure the note is really visible; note that we do not hide
  312.             veiled notes.
  313.         */
  314.         if((*npp)->state == Visible && (*npp)->mapped)
  315.             {
  316.             count++;
  317.             w_hidenote(*npp);
  318.             }
  319.         npp = (struct Note **) LLM_next(&root);
  320.         }
  321.     LLM_free(&root);
  322.     fprintf(errfp, "%s:  hid %d notes for RE {%s}\n",
  323.             myname, count, lp->ps_text);
  324.     }
  325.  
  326. cmd_movenote(lp)
  327.     struct ps_component *lp;
  328.     {
  329.     int  gotsrc, gotdst, gottitle, res, count;
  330.     struct SubDir *src_sp, *dst_sp, *sp;
  331.     struct Note **npp;
  332.     struct LLM_root root;
  333.     char src[MAXBUFLEN];
  334.     char dst[MAXBUFLEN];
  335.     char title[MAXBUFLEN];
  336.  
  337.     if(debug_on) fprintf(stderr, "cmd_movenote\n");
  338.     gotsrc = gotdst = gottitle = 0;
  339.     while(lp != NULL)
  340.         {
  341.         if(lp->ps_next == NULL) /* go by two's, so we need another param */
  342.             {
  343.             fprintf(errfp, "%s:  Incorrect parameters for move\n",
  344.                 myname);
  345.             return;
  346.             }
  347.         if(strcmp(lp->ps_text, "source") == 0)
  348.             {
  349.             lp = lp->ps_next;
  350.             strcpy(src, lp->ps_text);
  351.             gotsrc = 1;
  352.             lp = lp->ps_next;
  353.             }
  354.         else if(strcmp(lp->ps_text, "title") == 0)
  355.             {
  356.             lp = lp->ps_next;
  357.             strcpy(title, lp->ps_text);
  358.             gottitle = 1;
  359.             lp = lp->ps_next;
  360.             }
  361.         else if(strcmp(lp->ps_text, "destination") == 0)
  362.             {
  363.             lp = lp->ps_next;
  364.             strcpy(dst, lp->ps_text);
  365.             gotdst = 1;
  366.             lp = lp->ps_next;
  367.             }
  368.         else
  369.             {
  370.             fprintf(errfp, "%s:  Incorrect parameter {%s} for move\n",
  371.                 myname, lp->ps_text);
  372.             return;
  373.             }
  374.         }
  375.     if(!gotsrc)
  376.         {
  377.         fprintf(errfp, "%s:  Missing source folder for move\n",
  378.             myname);
  379.         return;
  380.         }
  381.     if(!gotdst)
  382.         {
  383.         fprintf(errfp, "%s:  Missing destination folder for move\n",
  384.             myname);
  385.         return;
  386.         }
  387.     if(!gottitle)
  388.         {
  389.         fprintf(errfp, "%s:  Missing title for move\n",
  390.             myname);
  391.         return;
  392.         }
  393.     src_sp = dst_sp = NULL;
  394.     sp = (struct SubDir *) LLM_first(&subdir_rt);
  395.     while(sp != NULL)
  396.         {
  397.         if(strcmp(src, sp->subdir) == 0) src_sp = sp;
  398.         if(strcmp(dst, sp->subdir) == 0) dst_sp = sp;
  399.         sp = (struct SubDir *) LLM_next(&subdir_rt);
  400.         }
  401.     if(src_sp == NULL)
  402.         {
  403.         fprintf(errfp, "%s:  Bad source folder {%s} for move\n",
  404.             myname, src);
  405.         return;
  406.         }
  407.     if(dst_sp == NULL)
  408.         {
  409.         fprintf(errfp, "%s:  Bad destination folder {%s} for move\n",
  410.             myname, dst);
  411.         return;
  412.         }
  413.     res = w_matchingnotes(&root, title, 0);
  414.     switch(res)
  415.         {
  416.         case  -1 :
  417.             fprintf(errfp, "%s:  Invalid RE for move command {%s}\n",
  418.                 myname, title);
  419.             return;
  420.             break;
  421.         case  -2 :
  422.             fprintf(errfp, "%s:  Memory allocation failure during move\n",
  423.                 myname);
  424.             LLM_free(&root);
  425.             return;
  426.             break;
  427.         }
  428.     count = 0;
  429.     npp = (struct Note **) LLM_first(&root);
  430.     while(npp != NULL)
  431.         {
  432.         if((*npp)->sp == src_sp) /* Make sure it's in the src folder */
  433.             {
  434.             if(debug_on)
  435.                 fprintf(stderr, "Moving {%s} from {%s} to {%s}...\n",
  436.                     (*npp)->ntitle, src, dst);
  437.             res = w_movenote(src_sp, dst_sp, *npp, ERRINLOG);
  438.             if(res == 0)
  439.                 {
  440.                 if(debug_on) fprintf(stderr, "    ...succeeded\n");
  441.                 count++;
  442.                 }
  443.             else if(debug_on) fprintf(stderr, "    ...failed\n");
  444.             }
  445.         npp = (struct Note **) LLM_next(&root);
  446.         }
  447.     fprintf(errfp, "%s:  %d notes moved successfully\n", myname, count);
  448.     }
  449.  
  450. cmd_newfolder(lp)
  451.     struct ps_component *lp;
  452.     {
  453.     if(debug_on) fprintf(stderr, "cmd_newfolder\n");
  454.     if(lp == NULL || lp->ps_next == NULL || strcmp(lp->ps_text, "folder") != 0)
  455.         {
  456.         fprintf(errfp,
  457.             "%s:  newfolder command requires folder name parameter\n", myname);
  458.         return;
  459.         }
  460.     lp = lp->ps_next;
  461.     w_newfolder(lp->ps_text, ERRINLOG);
  462.     }
  463.  
  464. cmd_newnote(lp)
  465.     struct ps_component *lp;
  466.     {
  467.     int  x, y;
  468.     int  gotrect, gottitle, gotfile, gotfolder;
  469.     struct SubDir *sp;
  470.     NoteState state;
  471.     Rect rect;
  472.     char folder[MAXBUFLEN];
  473.     char title[MAXBUFLEN];
  474.     char file[MAXBUFLEN];
  475.  
  476.     if(debug_on) fprintf(stderr, "cmd_newnote\n");
  477.     gotrect = gottitle = gotfile = gotfolder = 0;
  478.  
  479.     /* set up good defaults in case only half is specified */
  480.     w_popupxy(&x, &y, DEFWIDTH, DEFHEIGHT, DEFSPACING);
  481.     rect.r_left = x;
  482.     rect.r_top = y;
  483.     rect.r_width = DEFWIDTH;
  484.     rect.r_height = DEFHEIGHT;
  485.  
  486.     state = Visible;
  487.     while(lp != NULL)
  488.         {
  489.         if(strcmp(lp->ps_text, "folder") == 0)
  490.             {
  491.             if(lp->ps_next == NULL)
  492.                 {
  493.                 fprintf(errfp, "%s:  Missing folder name\n", myname);
  494.                 return;
  495.                 }
  496.             lp = lp->ps_next;
  497.             strcpy(folder, lp->ps_text);
  498.             gotfolder = 1;
  499.             lp = lp->ps_next;
  500.             }
  501.         else if(strcmp(lp->ps_text, "title") == 0)
  502.             {
  503.             if(lp->ps_next == NULL)
  504.                 {
  505.                 fprintf(errfp, "%s:  Missing title\n", myname);
  506.                 return;
  507.                 }
  508.             lp = lp->ps_next;
  509.             strcpy(title, lp->ps_text);
  510.             gottitle = 1;
  511.             lp = lp->ps_next;
  512.             }
  513.         else if(strcmp(lp->ps_text, "size") == 0)
  514.             {
  515.             if(lp->ps_next == NULL || lp->ps_next->ps_next == NULL)
  516.                 {
  517.                 fprintf(errfp, "%s:  Missing width or height\n", myname);
  518.                 return;
  519.                 }
  520.             gotrect = 1;
  521.             lp = lp->ps_next;
  522.             rect.r_width = atoi(lp->ps_text);
  523.             lp = lp->ps_next;
  524.             rect.r_height = atoi(lp->ps_text);
  525.             lp = lp->ps_next;
  526.             }
  527.         else if(strcmp(lp->ps_text, "location") == 0)
  528.             {
  529.             if(lp->ps_next == NULL || lp->ps_next->ps_next == NULL)
  530.                 {
  531.                 fprintf(errfp, "%s:  Missing x or y location\n", myname);
  532.                 return;
  533.                 }
  534.             gotrect = 1;
  535.             lp = lp->ps_next;
  536.             rect.r_left = atoi(lp->ps_text);
  537.             lp = lp->ps_next;
  538.             rect.r_top = atoi(lp->ps_text);
  539.             lp = lp->ps_next;
  540.             }
  541.         else if(strcmp(lp->ps_text, "hidden") == 0)
  542.             {
  543.             state = Hidden;
  544.             lp = lp->ps_next;
  545.             }
  546.         else if(strcmp(lp->ps_text, "visible") == 0)
  547.             {
  548.             state = Visible;
  549.             lp = lp->ps_next;
  550.             }
  551.         else if(strcmp(lp->ps_text, "veiled") == 0)
  552.             {
  553.             state = Veiled;
  554.             lp = lp->ps_next;
  555.             }
  556.         else if(strcmp(lp->ps_text, "file") == 0)
  557.             {
  558.             if(lp->ps_next == NULL)
  559.                 {
  560.                 fprintf(errfp, "%s:  Missing file name\n", myname);
  561.                 return;
  562.                 }
  563.             lp = lp->ps_next;
  564.             strcpy(file, lp->ps_text);
  565.             gotfile = 1;
  566.             lp = lp->ps_next;
  567.             }
  568.         else
  569.             {
  570.             fprintf(errfp, "%s:  Invalid parameter {%s}\n",
  571.                 myname, lp->ps_text);
  572.             return;
  573.             }
  574.         }
  575.     if(!gotfolder) strcpy(folder, "Miscellaneous");
  576.     sp = (struct SubDir *) LLM_first(&subdir_rt);
  577.     while(sp != NULL)
  578.         {
  579.         if(strcmp(folder, sp->subdir) == 0) break;
  580.         sp = (struct SubDir *) LLM_next(&subdir_rt);
  581.         }
  582.     if(sp == NULL)
  583.         {
  584.         fprintf(errfp, "%s:  Invalid folder {%s}\n",
  585.             myname, folder);
  586.         return;
  587.         }
  588.     w_newnote(sp, state, gotrect ? &rect : NULL, gottitle ? title : NULL,
  589.         gotfile ? file : NULL, ERRINLOG);
  590.     }
  591.  
  592. /*
  593.     This guy is a half baked state machine for printing notes.
  594.  
  595.     State 1 = Doing nothing.  Process command and get list of notes to print.
  596.               Start queuing of first note.
  597.     State 2 = Printing and called by child_death.  Kick off next queue command.
  598.     State 3 = Printing and got a real print command.  Add notes to list to
  599.               be printed.
  600.     State 4 = Not printing, called on child death, do nothing.
  601.  
  602.     The state machine is controlled by the variables:  printing, lp, adding
  603. */
  604.  
  605. cmd_printnote(lp)
  606.     struct ps_component *lp;
  607.     {
  608.     int  adding = 0;
  609.     struct Note **tnpp1, **tnpp2;
  610.     struct LLM_root addroot;
  611.     static int printing = 0;
  612.     static int  gotfldr, gottitle, res, count;
  613.     static struct SubDir *fldr_sp, *sp;
  614.     static struct Note **npp;
  615.     static struct LLM_root root;
  616.     static char fldr[MAXBUFLEN];
  617.     static char title[MAXBUFLEN];
  618.  
  619.     if(debug_on) fprintf(stderr, "cmd_printnote\n");
  620.     if(!printing && lp == NULL) return;
  621.     if(printing && lp != NULL)
  622.         {
  623.         /* need to add to list! */
  624.         adding = 1;
  625.         }
  626.     if(printing && lp == NULL)
  627.         {
  628.         npp = (struct Note **) LLM_next(&root);
  629.         if(npp == NULL)
  630.             {
  631.             printing = 0;
  632.             LLM_free(&root);
  633.             if(debug_on)
  634.                 fprintf(stderr, "Printed %d notes\n", count);
  635.             }
  636.         else
  637.             {
  638.             if(debug_on)
  639.                 fprintf(stderr, "Printing {%s} ...\n", (*npp)->ntitle);
  640.             w_printnote(*npp, ERRINLOG);
  641.             count++;
  642.             }
  643.         return;
  644.         }
  645.     gotfldr = gottitle = 0;
  646.     while(lp != NULL)
  647.         {
  648.         if(lp->ps_next == NULL) /* go by two's, so we need another param */
  649.             {
  650.             fprintf(errfp, "%s:  Incorrect parameters for print\n",
  651.                 myname);
  652.             return;
  653.             }
  654.         if(strcmp(lp->ps_text, "folder") == 0)
  655.             {
  656.             lp = lp->ps_next;
  657.             strcpy(fldr, lp->ps_text);
  658.             gotfldr = 1;
  659.             lp = lp->ps_next;
  660.             }
  661.         else if(strcmp(lp->ps_text, "title") == 0)
  662.             {
  663.             lp = lp->ps_next;
  664.             strcpy(title, lp->ps_text);
  665.             gottitle = 1;
  666.             lp = lp->ps_next;
  667.             }
  668.         else
  669.             {
  670.             fprintf(errfp, "%s:  Incorrect parameter {%s} for print\n",
  671.                 myname, lp->ps_text);
  672.             return;
  673.             }
  674.         }
  675.     if(!gotfldr)
  676.         {
  677.         fprintf(errfp, "%s:  Missing source folder for print\n",
  678.             myname);
  679.         return;
  680.         }
  681.     if(!gottitle)
  682.         {
  683.         fprintf(errfp, "%s:  Missing title for print\n",
  684.             myname);
  685.         return;
  686.         }
  687.     fldr_sp = NULL;
  688.     sp = (struct SubDir *) LLM_first(&subdir_rt);
  689.     while(sp != NULL)
  690.         {
  691.         if(strcmp(fldr, sp->subdir) == 0) fldr_sp = sp;
  692.         sp = (struct SubDir *) LLM_next(&subdir_rt);
  693.         }
  694.     if(fldr_sp == NULL)
  695.         {
  696.         fprintf(errfp, "%s:  Bad source folder {%s} for print\n",
  697.             myname, fldr);
  698.         return;
  699.         }
  700.     if(adding)
  701.         {
  702.         res = w_matchingnotes(&addroot, title, 0);
  703.         }
  704.     else
  705.         {
  706.         res = w_matchingnotes(&root, title, 0);
  707.         }
  708.     switch(res)
  709.         {
  710.         case  -1 :
  711.             fprintf(errfp, "%s:  Invalid RE for print command {%s}\n",
  712.                 myname, title);
  713.             return;
  714.             break;
  715.         case  -2 :
  716.             fprintf(errfp, "%s:  Memory allocation failure during print\n",
  717.                 myname);
  718.             LLM_free(&root);
  719.             return;
  720.             break;
  721.         }
  722.     /* get rid of matching titles not in target folder */
  723.     if(adding)
  724.         {
  725.         tnpp1 = (struct Note **) LLM_first(&addroot);
  726.         while(tnpp1 != NULL)
  727.             {
  728.             if((*tnpp1)->sp != fldr_sp)
  729.                 {
  730.                 LLM_delete(&addroot, (char *)tnpp1);
  731.                 tnpp1 = (struct Note **) LLM_first(&addroot); /* restart */
  732.                 }
  733.             else
  734.                 {
  735.                 tnpp1 = (struct Note **) LLM_next(&addroot);
  736.                 }
  737.             }
  738.         /* now append the new list onto the old one we are printing from */
  739.         tnpp1 = (struct Note **) LLM_first(&addroot);
  740.         while(tnpp1 != NULL)
  741.             {
  742.             tnpp2 = (struct Note **) LLM_add(&root);
  743.             if(tnpp2 == NULL) /* Gak! */
  744.                 {
  745.                 fprintf(errfp,
  746.                     "%s:  Memory allocation failure during print\n",
  747.                     myname);
  748.                 LLM_free(&addroot);
  749.                 return;
  750.                 }
  751.             *tnpp2 = *tnpp1;
  752.             tnpp1 = (struct Note **) LLM_next(&addroot);
  753.             }
  754.         LLM_free(&addroot);
  755.         /* no need to go further, printing should be in process */
  756.         return;
  757.         }
  758.     else
  759.         {
  760.         npp = (struct Note **) LLM_first(&root);
  761.         while(npp != NULL)
  762.             {
  763.             if((*npp)->sp != fldr_sp)
  764.                 {
  765.                 LLM_delete(&root, (char *)npp);
  766.                 npp = (struct Note **) LLM_first(&root); /* restart */
  767.                 }
  768.             else
  769.                 {
  770.                 npp = (struct Note **) LLM_next(&root);
  771.                 }
  772.             }
  773.         }
  774.     count = 0;
  775.     printing = 1;
  776.     npp = (struct Note **) LLM_first(&root);
  777.     if(npp == NULL)
  778.         {
  779.         printing = 0;
  780.         LLM_free(&root);
  781.         if(debug_on)
  782.             fprintf(stderr, "Printed %d notes\n", count);
  783.         }
  784.     else
  785.         {
  786.         if(debug_on)
  787.             fprintf(stderr, "Printing {%s} ...\n", (*npp)->ntitle);
  788.         w_printnote(*npp, ERRINLOG);
  789.         count++;
  790.         }
  791.     }
  792.  
  793. cmd_quit(lp)
  794.     struct ps_component *lp;
  795.     {
  796.     if(debug_on) fprintf(stderr, "cmd_quit\n");
  797.     fprintf(errfp, "%s:  Exiting due to quit command\n", myname);
  798.     (void) fclose(errfp);
  799.     (void) unlink(ctrlnam);
  800.     (void) unlink(ctrllck);
  801.     cleanup(0);
  802.     }
  803.  
  804. cmd_rename(lp)
  805.     struct ps_component *lp;
  806.     {
  807.     if(debug_on) fprintf(stderr, "cmd_rename\n");
  808.     fprintf(errfp, "%s:  Unimplemented command\n", myname);
  809.     }
  810.  
  811. cmd_veil(lp)
  812.     struct ps_component *lp;
  813.     {
  814.     int  count;
  815.     int  res;
  816.     struct Note **npp;
  817.     struct LLM_root root;
  818.  
  819.     if(debug_on) fprintf(stderr, "cmd_veil\n");
  820.     if(lp == NULL || lp->ps_next == NULL)
  821.         {
  822.         fprintf(errfp, "%s:  veil command requires title RE parameter\n",
  823.             myname);
  824.         return;
  825.         }
  826.     if(debug_on)
  827.         fprintf(stderr, "veil {%s} {%s}\n", lp->ps_text,
  828.             lp->ps_next->ps_text);
  829.     if(strcmp(lp->ps_text, "title") != 0)
  830.         {
  831.         fprintf(errfp, "%s:  veil command requires title keyword\n",
  832.             myname);
  833.         return;
  834.         }
  835.     lp = lp->ps_next;
  836.     /*
  837.         This is slightly different than for expose - we will probably get
  838.         matches for notes that are already hidden because of the way
  839.         w_matchingnotes works.  It knows how to a) find all non-visible notes,
  840.         and b) all notes.
  841.     */
  842.     res = w_matchingnotes(&root, lp->ps_text, 0);
  843.     switch(res)
  844.         {
  845.         case  -1 :
  846.             fprintf(errfp, "%s:  Invalid RE for veil command {%s}\n",
  847.                 myname, lp->ps_text);
  848.             return;
  849.             break;
  850.         case  -2 :
  851.             fprintf(errfp, "%s:  Memory allocation failure during veil\n",
  852.                 myname);
  853.             LLM_free(&root);
  854.             return;
  855.             break;
  856.         }
  857.     count = 0;
  858.     npp = (struct Note **) LLM_first(&root);
  859.     if(npp == NULL)
  860.         {
  861.         fprintf(errfp, "%s:  No matches found to veil for RE {%s}\n",
  862.             myname, lp->ps_text);
  863.         }
  864.     while(npp != NULL)
  865.         {
  866.         /*
  867.             Make sure the note is really visible; note that we do not veil
  868.             hidden notes.
  869.         */
  870.         if((*npp)->state == Visible && (*npp)->mapped)
  871.             {
  872.             count++;
  873.             w_veilnote(*npp);
  874.             }
  875.         npp = (struct Note **) LLM_next(&root);
  876.         }
  877.     LLM_free(&root);
  878.     fprintf(errfp, "%s:  veiled %d notes for RE {%s}\n",
  879.             myname, count, lp->ps_text);
  880.     }
  881.