home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume28 / yapp / part02 / edbuf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-29  |  11.0 KB  |  328 lines

  1. /* EDBUF.C */
  2. static    char sccsid[] = "@(#)edbuf.c 1.16 93/06/09 Copyright (c)1993 thalerd";
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include "config.h"
  8. #include "struct.h"
  9. #include "globals.h"
  10. #include "macro.h"
  11. #include "driver.h"
  12. #include "lib.h"
  13. #include "item.h"
  14. #include "edbuf.h"
  15. #include "help.h"
  16. #include "files.h"
  17. static FILE *file;
  18. static char post;
  19. static char oldmode;
  20. static int  resp;
  21.  
  22. /* Regarding mode: NOW USES oldmode
  23.  * Set mode back to RFP for respond command
  24.  * Enter command will set mode to OK itself
  25.  */
  26.  
  27. /******************************************************************************/
  28. /* MAIN TEXT ENTRY LOOP                                                       */
  29. /******************************************************************************/
  30. char              /* RETURNS: 1 on success, 0 on failure */
  31. cfbufr_open(flg)  /* ARGUMENTS: */
  32. short flg;        /*    File open type (r,w, etc) */
  33. {
  34.    char buff[MAX_LINE_LENGTH];
  35.  
  36.    sprintf(buff,"%s/cf.buffer",work);
  37.    if ((file=mopen(buff,flg))==NULL) return 0;
  38.    printf("Type \".\" to exit or \":help\".\n");
  39.    return 1;
  40. }
  41.  
  42. /******************************************************************************/
  43. char        /* RETURNS: 1 on post, 0 on abort */
  44. text_loop(new,res) /* ARGUMENTS: (none) */
  45. int new;
  46. int res;
  47. {
  48.    char ok=1,inbuff[MAX_LINE_LENGTH],
  49.         fromname[MAX_LINE_LENGTH],toname[MAX_LINE_LENGTH];
  50.    register int cpid,wpid;
  51.    int statusp;
  52.    struct stat st;
  53.  
  54.    resp = res;
  55.    if ((status & S_MOTIF) || (flags & O_EDALWAYS))
  56.       return edit(work,"cf.buffer",0);
  57.  
  58.    post=0;
  59.  
  60.    /* Fork & setuid down when creating cf.buffer */
  61.    if (cpid=fork()) { /* parent */
  62.       if (cpid<0) return -1; /* error: couldn't fork */
  63.       while ((wpid = wait(&statusp)) != cpid && wpid != -1);
  64.       post = !statusp;
  65.    } else { /* child */
  66.       if (setuid(getuid())) error("setuid","");
  67.       setgid(getgid());
  68.  
  69.       if (new) {
  70.          sprintf(fromname,"%s/cf.buffer",work);
  71.          if (!stat( fromname ,&st)) { /* cf.buffer exists */
  72.             sprintf(toname,"%s/cbf.%d",work,getpid());
  73.             if (rename(fromname,toname))
  74.                error("renaming cf.buffer to ",toname);
  75.          }
  76.       }
  77.  
  78.       printf("%s your %s%s\n",(new) ? "Enter"    : "(Continue", 
  79.                               (resp)? "response" : "text",
  80.                               (new) ? ":"        : " entry)" );
  81.       if (!cfbufr_open((new)? O_WPLUS : O_APLUS)) return 0; /* "w+" */
  82.  
  83.       oldmode = mode;
  84.       mode = M_TEXT;
  85.       while (mode==M_TEXT && ok) {
  86.          /* For optimization purposes, we do not allow seps in TEXT mode
  87.           * prompt.  This could be changed back if confsep would dump
  88.           * out most strings quickly without accessing the disk.
  89.           */
  90.          wputs(TEXT);
  91.          /* print_prompt(mode); */
  92.  
  93.          ok = (ngets(inbuff,st_glob.inp)!=NULL);
  94.          if (ok && (status & S_INT)) {
  95.             status &= ~S_INT; /* Clear interrupt */
  96.             ok = !get_yes((resp)? "Abort response? " : "Abort item? " );
  97.             if (!ok) post= -1;
  98.          }
  99.          /* printf("ok=%d inbuff=%s\n",ok,inbuff); */
  100.          if (!ok) {
  101.             printf("\n");
  102.             mode = oldmode; /* Ctrl-D same as "." */
  103.             post++; /* post on ^D or .  don't post on ^C */
  104.          } else if (inbuff[0]==':') {
  105.             if (inbuff[1]) ok = command(inbuff+1,0);
  106.             else           ok = command("e",0);
  107.          } else if ((flags & O_DOT) && !strcmp(inbuff,".")) {
  108.             mode = oldmode; /* done */
  109.             post = 1;
  110.          } else { /* Add to file buffer */
  111.             if (fprintf(file,"%s\n",inbuff)<0) ok=0;
  112.             else fflush(file);
  113.          }
  114.       }
  115.       mclose(file);
  116.       exit(!post);
  117.    } /* ENDFORK */
  118.  
  119.    return post;
  120. }
  121.  
  122. /* Commands available while in text entry mode */
  123. static dispatch_t text_cmd[]={
  124.    "q_uit",    text_abort,
  125.    "c_ommand", text_done,
  126.    "ok",       text_done,
  127.    "p_rint",   text_print,
  128.    "e_dit",    text_edit,
  129.    "v_isual",  text_edit,
  130.    "h_elp",    help,
  131.    "?",        help,
  132.    "cl_ear",   text_clear,
  133.    "em_pty",   text_clear,
  134.    "r_ead",    text_read,
  135.    "w_rite",   text_write,
  136.    0, 0
  137. };
  138.  
  139. /******************************************************************************/
  140. /* DISPATCH CONTROL TO APPROPRIATE TEXT COMMAND FUNCTION                      */
  141. /******************************************************************************/
  142. char                         /* RETURNS: 1 on abort, 0 else */
  143. text_cmd_dispatch(argc,argv) /* ARGUMENTS:                  */
  144. int    argc;                 /*    Number of arguments      */
  145. char **argv;                 /*    Argument list            */
  146. {
  147.    int i;
  148.  
  149.    for (i=0; text_cmd[i].name; i++)
  150.       if (match(argv[0],text_cmd[i].name))
  151.          return text_cmd[i].func(argc,argv);
  152.  
  153.    /* Command dispatch */
  154.    if (match(argv[0],"d_one") /* same as . on a new line */
  155.     ||      match(argv[0],"st_op") /* ? */
  156.     ||      match(argv[0],"ex_it"))/* ?*/{
  157.       mode = oldmode; post = 1; /* mark as done */ 
  158.    } else {
  159.       printf("Don't understand that!\n\n");
  160.       text_abort(argc,argv);
  161.    }
  162.    return 1;
  163. }
  164.  
  165. /******************************************************************************/
  166. /* READ TEXT FROM A FILE INTO THE BUFFER                                      */
  167. /******************************************************************************/
  168. int                  /* RETURNS: (nothing)     */
  169. text_read(argc,argv) /* ARGUMENTS:             */
  170. int argc;            /*    Number of arguments */
  171. char **argv;         /*    Argument list       */
  172. {
  173.    FILE *fp;
  174.    char buff[MAX_LINE_LENGTH];
  175.  
  176.    /* PicoSpan puts spaces into the filename, we don't */
  177.    if (argc!=2) {
  178.       printf("UNK Syntax: r filename\n");
  179.       return 1;
  180.    }
  181.  
  182.    /* This is done inside the secure portion
  183.     * writing to the cf.buffer file, so it's already secure
  184.     */
  185.    printf("Reading %s\n",argv[1]);
  186.    if ((fp=mopen(argv[1],O_R))==NULL) {
  187.       return 1;
  188.    }
  189.    while (ngets(buff,fp))
  190.       fprintf(file,"%s\n",buff);
  191.    mclose(fp);
  192.    return 1;
  193. }
  194.  
  195. /******************************************************************************/
  196. /* WRITE TEXT IN BUFFER OUT TO A FILE                                         */
  197. /******************************************************************************/
  198. int                  /* RETURNS: (nothing)     */
  199. text_write(argc,argv) /* ARGUMENTS:             */
  200. int argc;             /*    Number of arguments */
  201. char **argv;          /*    Argument list       */
  202. {
  203.    FILE *fp;
  204.    char buff[MAX_LINE_LENGTH];
  205.  
  206.    /* PicoSpan puts spaces into the filename, we don't */
  207.    if (argc!=2) {
  208.       printf("UNK Syntax: w filename\n");
  209.       return 1;
  210.    }
  211.  
  212.    /* This is done inside the secure portion
  213.     * writing to the cf.buffer file, so is already secure
  214.     */
  215.    printf("Writing %s\n",argv[1]);
  216.    if ((fp=mopen(argv[1],O_W))==NULL) { /* use normal umask */
  217.       return 1;
  218.    }
  219.    fseek(file,0L,0);
  220.    while (ngets(buff,file))
  221.       fprintf(fp,"%s\n",buff);
  222.    mclose(fp);
  223.    return 1;
  224. }
  225.  
  226. /******************************************************************************/
  227. /* DUMP TEXT IN BUFFER AND START OVER                                         */
  228. /******************************************************************************/
  229. int                   /* RETURNS: (nothing)     */
  230. text_clear(argc,argv) /* ARGUMENTS:             */
  231. int argc;             /*    Number of arguments */
  232. char **argv;          /*    Argument list       */
  233. {
  234.    mclose(file);
  235.    printf("Enter your %s:\n",(oldmode==M_OK)? "text" : "response" );
  236.    if (!cfbufr_open(O_WPLUS)) /* "w+" */
  237.       mode = oldmode; /* abort */
  238.    else 
  239.       mode = M_TEXT;
  240.    return 1;
  241. }
  242.  
  243. /******************************************************************************/
  244. /* REPRINT CURRENT CONTENTS OF BUFFER                                         */
  245. /******************************************************************************/
  246. int                   /* RETURNS: (nothing)     */
  247. text_print(argc,argv) /* ARGUMENTS:             */
  248. int argc;             /*    Number of arguments */
  249. char **argv;          /*    Argument list       */
  250. {
  251.    char buff[MAX_LINE_LENGTH];
  252.    fseek(file,0L,0);
  253.    while (ngets(buff,file) && !(status & S_INT))
  254.       printf(" %s\n",buff);
  255.    return 1;
  256. }
  257.  
  258. /******************************************************************************/
  259. /* INVOKE UNIX EDITOR ON THE BUFFER                                           */
  260. /******************************************************************************/
  261. int                  /* RETURNS: (nothing)     */
  262. text_edit(argc,argv) /* ARGUMENTS:             */
  263. int argc;            /*    Number of arguments */
  264. char **argv;         /*    Argument list       */
  265. {
  266.    char buff[MAX_LINE_LENGTH];
  267.    
  268.    mclose(file);
  269.    edit(work,"cf.buffer",(argv[0][0]=='v')); /* 'v_isual' check */
  270.    printf("(Continue your %s entry)\n",(resp)? "response" : "text" );
  271.    cfbufr_open(O_APLUS); /* a+ */
  272.    return 1;
  273. }
  274.  
  275. /******************************************************************************/
  276. /* ABORT TEXT ENTRY MODE                                                      */
  277. /******************************************************************************/
  278. int                   /* RETURNS: (nothing)     */
  279. text_abort(argc,argv) /* ARGUMENTS:             */
  280. int argc;             /*    Number of arguments */
  281. char **argv;          /*    Argument list       */
  282. {
  283.    if (get_yes("Ok to abandon text? ")) 
  284.       mode = oldmode;
  285.    return 1;
  286. }
  287.  
  288. /******************************************************************************/
  289. /* END TEXT ENTRY MODE AND POST IT                                            */
  290. /******************************************************************************/
  291. int                  /* RETURNS: (nothing)     */
  292. text_done(argc,argv) /* ARGUMENTS:             */
  293. int argc;            /*    Number of arguments */
  294. char **argv;         /*    Argument list       */
  295. {
  296.    /* Main EDB cmd loop */
  297.    mode = M_EDB;
  298.    while (mode==M_EDB && get_command(NULL));
  299.    return 1;
  300. }
  301.  
  302. /******************************************************************************/
  303. /* FIGURE OUT WHAT TO DO WHEN ESCAPING OUT OF TEXT MODE                       */
  304. /******************************************************************************/
  305. char             
  306. edb_cmd_dispatch(argc,argv) /* ARGUMENTS:             */
  307. int argc;                   /*    Number of arguments */
  308. char **argv;                /*    Argument list       */
  309. {
  310.    /* Command dispatch */
  311.    if      (match(argv[0],"n_on")
  312.     ||      match(argv[0],"nop_e")) {
  313.       /* printf("Response aborted!  Returning to current item.\n");*/
  314.       mode = oldmode;
  315.    } else if (match(argv[0],"y_es")
  316.     ||        match(argv[0],"ok"))  { post = 1; mode = oldmode; }
  317.    else if (match(argv[0],"ed_it"))         text_edit(argc,argv);
  318.    else if (match(argv[0],"ag_ain")
  319.     ||      match(argv[0],"c_ontinue"))     {
  320.       mode = M_TEXT;
  321.       printf("(Continue your text entry)\nType \".\" to exit or \":help\".\n");
  322.    } else if (match(argv[0],"pr_int"))      text_print(argc,argv);
  323.    else if (match(argv[0],"em_pty")
  324.     ||      match(argv[0],"cl_ear"))        text_clear(argc,argv);
  325.    else return misc_cmd_dispatch(argc,argv);
  326.    return 1;
  327. }
  328.