home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume17 / zoo2 / part05 / comment.c next >
C/C++ Source or Header  |  1989-02-01  |  10KB  |  314 lines

  1. #ifndef LINT
  2. static char sccsid[]="@(#) comment.c 2.14 88/01/24 12:42:13";
  3. #endif /* LINT */
  4.  
  5. /*
  6. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  7. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  8. */
  9.  
  10. #include "options.h"
  11. #include "portable.h"
  12. /* comment() */
  13. /* Updates comments */
  14.  
  15. /* buffer size for any one comment line */
  16. #define  COMMENT_LINE_SIZE 76
  17.  
  18. #define  MAX_COMMENT_SIZE  65535
  19. #include "zooio.h"
  20. #include "various.h"
  21.  
  22. #ifndef NOSIGNAL
  23. #include <signal.h>
  24. #endif
  25.  
  26. #include "zoo.h"
  27. #include "zoofns.h"
  28. #include "errors.i"
  29.  
  30. #ifdef LINT_ARGS
  31. void show_comment (struct direntry *, ZOOFILE, int, char *);
  32. get_comment (struct direntry *, ZOOFILE, char *);
  33. int needed (char *, struct direntry *, struct zoo_header *);
  34. #else
  35. void show_comment ();
  36. get_comment ();
  37. int needed ();
  38. #endif
  39.  
  40. void comment(zoo_path, option)
  41. char *zoo_path, *option;
  42. {
  43. #ifndef NOSIGNAL  
  44. int (*oldsignal)();
  45. #endif
  46. ZOOFILE zoo_file;                         /* stream for open archive */
  47. long next_ptr;                            /* pointers to within archive */
  48. long this_dir_offset;                     /* pointers to within archive */
  49. struct direntry direntry;                 /* directory entry */
  50. struct zoo_header zoo_header;
  51. int matched = 0;                          /* any files matched? */
  52. unsigned int zoo_date, zoo_time;          /* for restoring archive timestamp */
  53. char whichname[PATHSIZE];                 /* which name to use */
  54. #ifdef ZOOCOMMENT
  55. int acmt = 0;                                        /* if changing archive comment */
  56. #endif
  57.  
  58. /* on entry option points to first letter */
  59. option++;                                            /* skip 'c' */
  60. #ifdef ZOOCOMMENT
  61. while (*option != '\0') {
  62.     if (*option == 'A') {
  63.         acmt++;                                        /* changing archive comment */
  64.         option++;
  65.     } else
  66.        prterror ('f', inv_option, *option);
  67. }
  68. #else
  69. if (*option != '\0')
  70.     prterror ('f', inv_option, *option);
  71. #endif /* ZOOCOMMENT */
  72.  
  73. if ((zoo_file = zooopen (zoo_path, Z_RDWR)) == NOFILE)
  74.    prterror ('f', could_not_open, zoo_path);
  75.  
  76. /* save archive timestamp */
  77. #ifdef GETUTIME
  78. getutime (zoo_path, &zoo_date, &zoo_time);
  79. #else
  80. gettime (zoo_file, &zoo_date, &zoo_time);
  81. #endif
  82.  
  83. /* read header and rewrite with updated version numbers, but ask user to pack
  84. archive first if archive comment is to be added and header type is 0 */
  85. #ifdef ZOOCOMMENT
  86. if (acmt)
  87.     rwheader (&zoo_header, zoo_file, 0);
  88. else
  89.     rwheader (&zoo_header, zoo_file, 1);
  90. #else
  91. rwheader (&zoo_header, zoo_file, 1);
  92. #endif
  93.  
  94. #ifdef ZOOCOMMENT
  95. /* if archive comment being added, handle it and return */
  96. if (acmt) {
  97.     void do_acmt PARMS ((struct zoo_header *, ZOOFILE, char *));
  98.     do_acmt (&zoo_header, zoo_file, zoo_path);
  99. #ifdef NIXTIME
  100.     zooclose (zoo_file);
  101.     setutime (zoo_path, zoo_date, zoo_time);    /* restore timestamp */
  102. #else
  103.     settime (zoo_file, zoo_date, zoo_time);    /* restore timestamp */
  104.     zooclose (zoo_file);
  105. #endif
  106.     return;
  107. }
  108. #endif /* ZOOCOMMENT */
  109.  
  110. /* Loop through and add comments for matching files */
  111. while (1) {
  112.    this_dir_offset = zootell (zoo_file);  /* save pos'n of this dir entry */
  113.    readdir (&direntry, zoo_file, 1);      /* read directory entry */
  114.    next_ptr = direntry.next;              /* ptr to next dir entry */
  115.  
  116.    /* exit on end of directory chain or end of file */
  117.    if (next_ptr == 0L || feof(stdin))
  118.       break;
  119.  
  120.     strcpy (whichname, fullpath (&direntry));        /* full pathname */
  121.     add_version (whichname, &direntry);                /* add version suffix */
  122.    /* add comments for matching non-deleted files */
  123.    if (!direntry.deleted && needed (whichname, &direntry, &zoo_header)) {
  124.       matched++;
  125.       show_comment (&direntry, zoo_file, 1, whichname);
  126.       get_comment (&direntry, zoo_file, whichname);
  127.       zooseek (zoo_file, this_dir_offset, 0);
  128. #ifndef NOSIGNAL
  129.       oldsignal = signal (SIGINT, SIG_IGN);
  130. #endif
  131.       fwr_dir (&direntry, zoo_file);
  132. #ifndef NOSIGNAL
  133.       signal (SIGINT, oldsignal);
  134. #endif
  135.    }
  136.    zooseek (zoo_file, next_ptr, 0);   /* ..seek to next dir entry */
  137. } /* end while */
  138.  
  139. #ifdef NIXTIME
  140. zooclose (zoo_file);
  141. setutime (zoo_path, zoo_date, zoo_time);    /* restore timestamp */
  142. #else
  143. settime (zoo_file, zoo_date, zoo_time);    /* restore timestamp */
  144. zooclose (zoo_file);
  145. #endif
  146.  
  147. if (!matched)
  148.    printf ("Zoo:  %s", no_match);
  149. } /* comment */
  150.  
  151. /* show_comment() */
  152. /* shows comment on screen.  If show=1, says "Current comment is..." */
  153.  
  154. void show_comment (direntry, zoo_file, show, name)
  155. struct direntry *direntry;
  156. ZOOFILE zoo_file;
  157. int show;
  158. char *name;       /* name of file for which comment is being added */
  159. {
  160.    if (direntry->cmt_size != 0) {
  161.       unsigned int i;
  162.       char ch;
  163.       int newline = 1;
  164.       zooseek (zoo_file, direntry->comment, 0);   
  165.       if (show)
  166.          printf ("Current comment for %s is:\n", name);
  167.       for (i = 0; i < direntry->cmt_size; i++) {/* show it */
  168.          ch = zgetc (zoo_file) & 0x7f;          /* 7 bits only */
  169.          if (newline)
  170.             printf (" |");    /* indent and mark comment lines thus */
  171.          zputchar (ch);
  172.          if (ch == '\n')
  173.             newline = 1;
  174.          else
  175.             newline = 0;
  176.       }
  177.       if (!newline)              /* always terminate with newline */
  178.          zputchar ('\n');
  179.    }
  180. } /* show_comment() */
  181.  
  182.  
  183. /* get_comment() */
  184. /* Shows user old comment and updates it */
  185.  
  186. /* INPUT:
  187.    direntry points to current directory entry.
  188.    zoo_file is archive file.
  189.    this_path is full pathname of file being updated/added.
  190.  
  191.    OUTPUT:
  192.    Comment is added to file and supplied directory entry is updated
  193.    with comment size and seek position but directory entry is
  194.    not written to file.  Exceptions:  If RETURN is hit as first line,
  195.    previous comment is left unchanged.  If /END is hit, previous
  196.    comment is superseded, even if new comment is null.
  197. */
  198.  
  199. char cmt_prompt[]="[Enter %scomment for %s then type /END]\n";
  200.  
  201. get_comment (direntry, zoo_file, this_path)  /* update comment */
  202. register struct direntry *direntry;
  203. ZOOFILE zoo_file;
  204. char *this_path;
  205. {
  206.    unsigned int line_count = 0;        /* count of new comment lines */
  207.  
  208.    zooseek (zoo_file, 0L, 2);            /* ready to append new comment */
  209. #if 0
  210.    fprintf (stderr, "[Enter comment for %s then type /END]\n", this_path);
  211. #else
  212.    fprintf (stderr, cmt_prompt, "", this_path);
  213. #endif
  214.    while (1) {
  215.       char cmt_line[COMMENT_LINE_SIZE];
  216.       int cmt_size;
  217.       if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
  218.          break;
  219.       line_count++;
  220.       if (line_count == 1) {                 /* first line typed */
  221.          if (!strcmp (cmt_line, "\n"))   /* exit if first line blank */
  222.             break;
  223.          direntry->comment = zootell (zoo_file);
  224.          direntry->cmt_size = 0;
  225.       }
  226.       if (!strcmpi (cmt_line, "/end\n"))
  227.          break;
  228.       cmt_size = strlen (cmt_line);
  229.       if (MAX_COMMENT_SIZE - direntry->cmt_size > cmt_size) {
  230.          direntry->cmt_size += (unsigned int) cmt_size;
  231.          if (zoowrite (zoo_file, cmt_line, cmt_size) < cmt_size)
  232.             prterror ('f', disk_full);
  233.       }
  234.    } /* end while */
  235. } /* get_comment() */
  236.  
  237. #ifdef ZOOCOMMENT
  238. /*
  239. do_acmt() updates archive comment by showing it to user and 
  240. requesting a new one.  Typed input terminates as with file comment,
  241. i.e., empty initial line leaves comment unchanged, case-insensitive
  242. "/end" terminates input comment.
  243. */
  244. void do_acmt (zoo_header, zoo_file, zoo_path)
  245. struct zoo_header *zoo_header;
  246. ZOOFILE zoo_file;
  247. char *zoo_path;
  248. {
  249.    unsigned int line_count = 0;        /* count of new comment lines */
  250.     void show_acmt PARMS ((struct zoo_header *, ZOOFILE, int));
  251.  
  252.     show_acmt (zoo_header, zoo_file, 1);    /* show current archive comment */
  253.    zooseek (zoo_file, 0L, 2);            /* ready to append new comment */
  254. #if 0
  255.    fprintf (stderr, "[Enter archive comment for %s then type /END]\n", 
  256.                             zoo_path);
  257. #else
  258.    fprintf (stderr, cmt_prompt, "archive ", zoo_path);
  259. #endif
  260.  
  261.    while (1) {
  262.       char cmt_line[COMMENT_LINE_SIZE];
  263.       int cmt_size;
  264.       if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
  265.          break;
  266.       line_count++;
  267.       if (line_count == 1) {                 /* first line typed */
  268.          if (!strcmp (cmt_line, "\n"))   /* exit if first line blank */
  269.             break;
  270.          zoo_header->acmt_pos = zootell (zoo_file);
  271.          zoo_header->acmt_len = 0;
  272.       }
  273.       if (!strcmpi (cmt_line, "/end\n"))
  274.          break;
  275.       cmt_size = strlen (cmt_line);
  276.       if (MAX_COMMENT_SIZE - zoo_header->acmt_len > cmt_size) {
  277.          zoo_header->acmt_len += (unsigned int) cmt_size;
  278.          if (zoowrite (zoo_file, cmt_line, cmt_size) < cmt_size)
  279.             prterror ('f', disk_full);
  280.       }
  281.    } /* end while */
  282.     zooseek (zoo_file, 0L, 0);                    /* seek back to beginning */
  283.     fwr_zooh (zoo_header, zoo_file);            /* write update zoo_header */
  284. } /* do_acmt() */
  285. #endif /* ZOOCOMMENT */
  286.  
  287. /* Prints archive comment.  If show==1, says "Current archive comment is:" */
  288. void show_acmt (zoo_header, zoo_file, show)
  289. struct zoo_header *zoo_header;
  290. ZOOFILE zoo_file;
  291. int show;
  292. {
  293.    if (zoo_header->zoo_start != FIXED_OFFSET && zoo_header->acmt_len > 0) {
  294.       unsigned int i;
  295.       char ch;
  296.       int newline = 1;
  297.       zooseek (zoo_file, zoo_header->acmt_pos, 0);   
  298.         if (show)
  299.           printf ("Current archive comment is:\n");
  300.       for (i = 0; i < zoo_header->acmt_len; i++) {/* show it */
  301.          ch = zgetc (zoo_file) & 0x7f;          /* 7 bits only */
  302.          if (newline)
  303.             printf (">> ");        /* indent and mark comment lines thus */
  304.          zputchar (ch);
  305.          if (ch == '\n')
  306.             newline = 1;
  307.          else
  308.             newline = 0;
  309.       }
  310.       if (!newline)              /* always terminate with newline */
  311.          zputchar ('\n');
  312.    }
  313. } /* show_acmt() */
  314.