home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl560.zip / ext / SDBM_File / sdbm / dbe.c < prev    next >
C/C++ Source or Header  |  1999-07-20  |  10KB  |  436 lines

  1. #include <stdio.h>
  2. #ifndef VMS
  3. #include <sys/file.h>
  4. #include <ndbm.h>
  5. #else
  6. #include "file.h"
  7. #include "ndbm.h"
  8. #endif
  9. #include <ctype.h>
  10.  
  11. /***************************************************************************\
  12. **                                                                         **
  13. **   Function name: getopt()                                               **
  14. **   Author:        Henry Spencer, UofT                                    **
  15. **   Coding date:   84/04/28                                               **
  16. **                                                                         **
  17. **   Description:                                                          **
  18. **                                                                         **
  19. **   Parses argv[] for arguments.                                          **
  20. **   Works with Whitesmith's C compiler.                                   **
  21. **                                                                         **
  22. **   Inputs   - The number of arguments                                    **
  23. **            - The base address of the array of arguments                 **
  24. **            - A string listing the valid options (':' indicates an       **
  25. **              argument to the preceding option is required, a ';'        **
  26. **              indicates an argument to the preceding option is optional) **
  27. **                                                                         **
  28. **   Outputs  - Returns the next option character,                         **
  29. **              '?' for non '-' arguments                                  **
  30. **              or ':' when there is no more arguments.                    **
  31. **                                                                         **
  32. **   Side Effects + The argument to an option is pointed to by 'optarg'    **
  33. **                                                                         **
  34. *****************************************************************************
  35. **                                                                         **
  36. **   REVISION HISTORY:                                                     **
  37. **                                                                         **
  38. **     DATE           NAME                        DESCRIPTION              **
  39. **   YY/MM/DD  ------------------   ------------------------------------   **
  40. **   88/10/20  Janick Bergeron      Returns '?' on unamed arguments        **
  41. **                                  returns '!' on unknown options         **
  42. **                                  and 'EOF' only when exhausted.         **
  43. **   88/11/18  Janick Bergeron      Return ':' when no more arguments      **
  44. **   89/08/11  Janick Bergeron      Optional optarg when ';' in optstring  **
  45. **                                                                         **
  46. \***************************************************************************/
  47.  
  48. char *optarg;                   /* Global argument pointer. */
  49.  
  50. #ifdef VMS
  51. #define index  strchr
  52. #endif
  53.  
  54. char
  55. getopt(int argc, char **argv, char *optstring)
  56. {
  57.     register int c;
  58.     register char *place;
  59.     extern char *index();
  60.     static int optind = 0;
  61.     static char *scan = NULL;
  62.  
  63.     optarg = NULL;
  64.  
  65.     if (scan == NULL || *scan == '\0') {
  66.  
  67.         if (optind == 0)
  68.             optind++;
  69.         if (optind >= argc)
  70.             return ':';
  71.  
  72.         optarg = place = argv[optind++];
  73.         if (place[0] != '-' || place[1] == '\0')
  74.             return '?';
  75.         if (place[1] == '-' && place[2] == '\0')
  76.             return '?';
  77.         scan = place + 1;
  78.     }
  79.  
  80.     c = *scan++;
  81.     place = index(optstring, c);
  82.     if (place == NULL || c == ':' || c == ';') {
  83.  
  84.         (void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
  85.         scan = NULL;
  86.         return '!';
  87.     }
  88.     if (*++place == ':') {
  89.  
  90.         if (*scan != '\0') {
  91.  
  92.             optarg = scan;
  93.             scan = NULL;
  94.  
  95.         }
  96.         else {
  97.  
  98.             if (optind >= argc) {
  99.  
  100.                 (void) fprintf(stderr, "%s: %c requires an argument\n",
  101.                            argv[0], c);
  102.                 return '!';
  103.             }
  104.             optarg = argv[optind];
  105.             optind++;
  106.         }
  107.     }
  108.     else if (*place == ';') {
  109.  
  110.         if (*scan != '\0') {
  111.  
  112.             optarg = scan;
  113.             scan = NULL;
  114.  
  115.         }
  116.         else {
  117.  
  118.             if (optind >= argc || *argv[optind] == '-')
  119.                 optarg = NULL;
  120.             else {
  121.                 optarg = argv[optind];
  122.                 optind++;
  123.             }
  124.         }
  125.     }
  126.     return c;
  127. }
  128.  
  129.  
  130. void
  131. print_datum(datum db)
  132. {
  133.     int i;
  134.  
  135.     putchar('"');
  136.     for (i = 0; i < db.dsize; i++) {
  137.         if (isprint((unsigned char)db.dptr[i]))
  138.             putchar(db.dptr[i]);
  139.         else {
  140.             putchar('\\');
  141.             putchar('0' + ((db.dptr[i] >> 6) & 0x07));
  142.             putchar('0' + ((db.dptr[i] >> 3) & 0x07));
  143.             putchar('0' + (db.dptr[i] & 0x07));
  144.         }
  145.     }
  146.     putchar('"');
  147. }
  148.  
  149.  
  150. datum
  151. read_datum(char *s)
  152. {
  153.     datum db;
  154.     char *p;
  155.     int i;
  156.  
  157.     db.dsize = 0;
  158.     db.dptr = (char *) malloc(strlen(s) * sizeof(char));
  159.     if (!db.dptr)
  160.         oops("cannot get memory");
  161.  
  162.     for (p = db.dptr; *s != '\0'; p++, db.dsize++, s++) {
  163.         if (*s == '\\') {
  164.             if (*++s == 'n')
  165.                 *p = '\n';
  166.             else if (*s == 'r')
  167.                 *p = '\r';
  168.             else if (*s == 'f')
  169.                 *p = '\f';
  170.             else if (*s == 't')
  171.                 *p = '\t';
  172.             else if (isdigit((unsigned char)*s)
  173.                  && isdigit((unsigned char)*(s + 1))
  174.                  && isdigit((unsigned char)*(s + 2)))
  175.             {
  176.                 i = (*s++ - '0') << 6;
  177.                 i |= (*s++ - '0') << 3;
  178.                 i |= *s - '0';
  179.                 *p = i;
  180.             }
  181.             else if (*s == '0')
  182.                 *p = '\0';
  183.             else
  184.                 *p = *s;
  185.         }
  186.         else
  187.             *p = *s;
  188.     }
  189.  
  190.     return db;
  191. }
  192.  
  193.  
  194. char *
  195. key2s(datum db)
  196. {
  197.     char *buf;
  198.     char *p1, *p2;
  199.  
  200.     buf = (char *) malloc((db.dsize + 1) * sizeof(char));
  201.     if (!buf)
  202.         oops("cannot get memory");
  203.     for (p1 = buf, p2 = db.dptr; *p2 != '\0'; *p1++ = *p2++);
  204.     *p1 = '\0';
  205.     return buf;
  206. }
  207.  
  208. int
  209. main(int argc, char **argv)
  210. {
  211.     typedef enum {
  212.         YOW, FETCH, STORE, DELETE, SCAN, REGEXP
  213.     } commands;
  214.     char opt;
  215.     int flags;
  216.     int giveusage = 0;
  217.     int verbose = 0;
  218.     commands what = YOW;
  219.     char *comarg[3];
  220.     int st_flag = DBM_INSERT;
  221.     int argn;
  222.     DBM *db;
  223.     datum key;
  224.     datum content;
  225.  
  226.     flags = O_RDWR;
  227.     argn = 0;
  228.  
  229.     while ((opt = getopt(argc, argv, "acdfFm:rstvx")) != ':') {
  230.         switch (opt) {
  231.         case 'a':
  232.             what = SCAN;
  233.             break;
  234.         case 'c':
  235.             flags |= O_CREAT;
  236.             break;
  237.         case 'd':
  238.             what = DELETE;
  239.             break;
  240.         case 'f':
  241.             what = FETCH;
  242.             break;
  243.         case 'F':
  244.             what = REGEXP;
  245.             break;
  246.         case 'm':
  247.             flags &= ~(000007);
  248.             if (strcmp(optarg, "r") == 0)
  249.                 flags |= O_RDONLY;
  250.             else if (strcmp(optarg, "w") == 0)
  251.                 flags |= O_WRONLY;
  252.             else if (strcmp(optarg, "rw") == 0)
  253.                 flags |= O_RDWR;
  254.             else {
  255.                 fprintf(stderr, "Invalid mode: \"%s\"\n", optarg);
  256.                 giveusage = 1;
  257.             }
  258.             break;
  259.         case 'r':
  260.             st_flag = DBM_REPLACE;
  261.             break;
  262.         case 's':
  263.             what = STORE;
  264.             break;
  265.         case 't':
  266.             flags |= O_TRUNC;
  267.             break;
  268.         case 'v':
  269.             verbose = 1;
  270.             break;
  271.         case 'x':
  272.             flags |= O_EXCL;
  273.             break;
  274.         case '!':
  275.             giveusage = 1;
  276.             break;
  277.         case '?':
  278.             if (argn < 3)
  279.                 comarg[argn++] = optarg;
  280.             else {
  281.                 fprintf(stderr, "Too many arguments.\n");
  282.                 giveusage = 1;
  283.             }
  284.             break;
  285.         }
  286.     }
  287.  
  288.     if (giveusage || what == YOW || argn < 1) {
  289.         fprintf(stderr, "Usage: %s databse [-m r|w|rw] [-crtx] -a|-d|-f|-F|-s [key [content]]\n", argv[0]);
  290.         exit(-1);
  291.     }
  292.  
  293.     if ((db = dbm_open(comarg[0], flags, 0777)) == NULL) {
  294.         fprintf(stderr, "Error opening database \"%s\"\n", comarg[0]);
  295.         exit(-1);
  296.     }
  297.  
  298.     if (argn > 1)
  299.         key = read_datum(comarg[1]);
  300.     if (argn > 2)
  301.         content = read_datum(comarg[2]);
  302.  
  303.     switch (what) {
  304.  
  305.     case SCAN:
  306.         key = dbm_firstkey(db);
  307.         if (dbm_error(db)) {
  308.             fprintf(stderr, "Error when fetching first key\n");
  309.             goto db_exit;
  310.         }
  311.         while (key.dptr != NULL) {
  312.             content = dbm_fetch(db, key);
  313.             if (dbm_error(db)) {
  314.                 fprintf(stderr, "Error when fetching ");
  315.                 print_datum(key);
  316.                 printf("\n");
  317.                 goto db_exit;
  318.             }
  319.             print_datum(key);
  320.             printf(": ");
  321.             print_datum(content);
  322.             printf("\n");
  323.             if (dbm_error(db)) {
  324.                 fprintf(stderr, "Error when fetching next key\n");
  325.                 goto db_exit;
  326.             }
  327.             key = dbm_nextkey(db);
  328.         }
  329.         break;
  330.  
  331.     case REGEXP:
  332.         if (argn < 2) {
  333.             fprintf(stderr, "Missing regular expression.\n");
  334.             goto db_exit;
  335.         }
  336.         if (re_comp(comarg[1])) {
  337.             fprintf(stderr, "Invalid regular expression\n");
  338.             goto db_exit;
  339.         }
  340.         key = dbm_firstkey(db);
  341.         if (dbm_error(db)) {
  342.             fprintf(stderr, "Error when fetching first key\n");
  343.             goto db_exit;
  344.         }
  345.         while (key.dptr != NULL) {
  346.             if (re_exec(key2s(key))) {
  347.                 content = dbm_fetch(db, key);
  348.                 if (dbm_error(db)) {
  349.                     fprintf(stderr, "Error when fetching ");
  350.                     print_datum(key);
  351.                     printf("\n");
  352.                     goto db_exit;
  353.                 }
  354.                 print_datum(key);
  355.                 printf(": ");
  356.                 print_datum(content);
  357.                 printf("\n");
  358.                 if (dbm_error(db)) {
  359.                     fprintf(stderr, "Error when fetching next key\n");
  360.                     goto db_exit;
  361.                 }
  362.             }
  363.             key = dbm_nextkey(db);
  364.         }
  365.         break;
  366.  
  367.     case FETCH:
  368.         if (argn < 2) {
  369.             fprintf(stderr, "Missing fetch key.\n");
  370.             goto db_exit;
  371.         }
  372.         content = dbm_fetch(db, key);
  373.         if (dbm_error(db)) {
  374.             fprintf(stderr, "Error when fetching ");
  375.             print_datum(key);
  376.             printf("\n");
  377.             goto db_exit;
  378.         }
  379.         if (content.dptr == NULL) {
  380.             fprintf(stderr, "Cannot find ");
  381.             print_datum(key);
  382.             printf("\n");
  383.             goto db_exit;
  384.         }
  385.         print_datum(key);
  386.         printf(": ");
  387.         print_datum(content);
  388.         printf("\n");
  389.         break;
  390.  
  391.     case DELETE:
  392.         if (argn < 2) {
  393.             fprintf(stderr, "Missing delete key.\n");
  394.             goto db_exit;
  395.         }
  396.         if (dbm_delete(db, key) || dbm_error(db)) {
  397.             fprintf(stderr, "Error when deleting ");
  398.             print_datum(key);
  399.             printf("\n");
  400.             goto db_exit;
  401.         }
  402.         if (verbose) {
  403.             print_datum(key);
  404.             printf(": DELETED\n");
  405.         }
  406.         break;
  407.  
  408.     case STORE:
  409.         if (argn < 3) {
  410.             fprintf(stderr, "Missing key and/or content.\n");
  411.             goto db_exit;
  412.         }
  413.         if (dbm_store(db, key, content, st_flag) || dbm_error(db)) {
  414.             fprintf(stderr, "Error when storing ");
  415.             print_datum(key);
  416.             printf("\n");
  417.             goto db_exit;
  418.         }
  419.         if (verbose) {
  420.             print_datum(key);
  421.             printf(": ");
  422.             print_datum(content);
  423.             printf(" STORED\n");
  424.         }
  425.         break;
  426.     }
  427.  
  428. db_exit:
  429.     dbm_clearerr(db);
  430.     dbm_close(db);
  431.     if (dbm_error(db)) {
  432.         fprintf(stderr, "Error closing database \"%s\"\n", comarg[0]);
  433.         exit(-1);
  434.     }
  435. }
  436.