home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / unix / emx / test / eatool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  11.0 KB  |  470 lines

  1. /* eatool.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
  2.  
  3. #define INCL_DOSFILEMGR
  4. #include <os2.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <getopt.h>
  9. #include <io.h>
  10. #include <sys/nls.h>
  11. #include <sys/ead.h>
  12.  
  13. #define FALSE 0
  14. #define TRUE  1
  15.  
  16. enum actions
  17. {
  18.   ACTION_NONE,
  19.   ACTION_ADD,
  20.   ACTION_DISCARD,
  21.   ACTION_LIST,
  22.   ACTION_GET,
  23.   ACTION_MERGE,
  24.   ACTION_PUT,
  25.   ACTION_REMOVE
  26. };
  27.  
  28. static int debugging = FALSE;
  29. static enum actions action = ACTION_NONE;
  30. static _ead empty_ead = NULL;
  31.  
  32.  
  33. static void do_add (const char *path, const char *name, const char *value)
  34. {
  35.   int i, size;
  36.   _ead ead;
  37.   char *buf, *uname;
  38.  
  39.   uname = strdup (name);
  40.   if (uname == NULL)
  41.     {
  42.       fprintf (stderr, "Out of memory\n");
  43.       exit (2);
  44.     }
  45.   _nls_strupr (uname);
  46.   ead = _ead_create ();
  47.   if (ead == NULL)
  48.     {
  49.       perror (NULL);
  50.       exit (2);
  51.     }
  52.   size = strlen (value);
  53.   buf = malloc (size + 4);
  54.   if (buf == NULL)
  55.     {
  56.       fprintf (stderr, "Out of memory\n");
  57.       exit (2);
  58.     }
  59.   ((USHORT *)buf)[0] = EAT_ASCII;
  60.   ((USHORT *)buf)[1] = size;
  61.   memcpy (buf+4, value, size);
  62.   if (_ead_add (ead, uname, 0, buf, size+4) < 0)
  63.     {
  64.       perror (path);
  65.       exit (2);
  66.     }
  67.   if (strcmp (path, "-") == 0)
  68.     i = _ead_write (ead, NULL, fileno (stdout), _EAD_MERGE);
  69.   else
  70.     i = _ead_write (ead, path, 0, _EAD_MERGE);
  71.   if (i < 0)
  72.     perror (path);
  73.   free (buf); free (uname);
  74.   _ead_destroy (ead);
  75. }
  76.  
  77.  
  78. static void do_remove (const char *path, const char *name)
  79. {
  80.   _ead ead;
  81.   int i;
  82.   char *uname;
  83.  
  84.   ead = _ead_create ();
  85.   if (ead == NULL)
  86.     {
  87.       perror (NULL);
  88.       exit (2);
  89.     }
  90.   uname = strdup (name);
  91.   if (uname == NULL)
  92.     {
  93.       fprintf (stderr, "Out of memory\n");
  94.       exit (2);
  95.     }
  96.   _nls_strupr (uname);
  97.   if (_ead_read (ead, path, 0, 0) < 0)
  98.     perror (path);
  99.   i = _ead_find (ead, uname);
  100.   if (i < 0)
  101.     {
  102.       perror (path);
  103.       exit (2);
  104.     }
  105.   if (_ead_delete (ead, i) < 0)
  106.     {
  107.       perror ("_ead_delete");
  108.       exit (2);
  109.     }
  110.   if (_ead_write (ead, path, 0, 0) < 0)
  111.     perror (path);
  112.   free (uname);
  113.   _ead_destroy (ead);
  114. }
  115.  
  116.  
  117. static void do_discard (const char *path)
  118. {
  119.   int i;
  120.  
  121.   if (empty_ead == NULL)
  122.     {
  123.       empty_ead = _ead_create ();
  124.       if (empty_ead == NULL)
  125.         {
  126.           perror (NULL);
  127.           exit (2);
  128.         }
  129.     }
  130.   if (strcmp (path, "-") == 0)
  131.     i = _ead_write (empty_ead, NULL, fileno (stdout), 0);
  132.   else
  133.     i = _ead_write (empty_ead, path, 0, 0);
  134.   if (i < 0)
  135.     perror (path);
  136. }
  137.  
  138.  
  139. static void do_list (const char *path)
  140. {
  141.   _ead ead;
  142.   int i, n, nlen, vsize;
  143.   const char *name, *value;
  144.  
  145.   ead = _ead_create ();
  146.   if (ead == NULL)
  147.     {
  148.       perror (NULL);
  149.       exit (2);
  150.     }
  151.   if (strcmp (path, "-") == 0)
  152.     i = _ead_read (ead, NULL, fileno (stdin), 0);
  153.   else
  154.     i = _ead_read (ead, path, 0, 0);
  155.   if (i < 0)
  156.     perror (path);
  157.   else
  158.     {
  159.       if (debugging)
  160.         printf ("%s (%d %d %d):\n", path,
  161.                 _ead_name_len (ead, 0), _ead_value_size (ead, 0),
  162.                 _ead_fea2list_size (ead));
  163.       else
  164.         printf ("%s:\n", path);
  165.       _ead_sort (ead);
  166.       n = _ead_count (ead);
  167.       for (i = 1; i <= n; ++i)
  168.         {
  169.           name = _ead_get_name (ead, i);
  170.           if (name == NULL)
  171.             perror (path);
  172.           else
  173.             {
  174.               vsize = _ead_value_size (ead, i);
  175.               if (vsize < 0) perror (path);
  176.               if (debugging)
  177.                 {
  178.                   nlen = _ead_name_len (ead, i);
  179.                   if (nlen < 0) perror (path);
  180.                   printf ("  %s (%d): ", name, nlen);
  181.                 }
  182.               else
  183.                 printf ("  %s: ", name);
  184.               if (vsize >= 4)
  185.                 {
  186.                   value = _ead_get_value (ead, i);
  187.                   if (value == NULL)
  188.                     perror (path);
  189.                   else
  190.                     switch (*(USHORT *)value)
  191.                       {
  192.                       case EAT_ASCII:
  193.                         printf ("\"");
  194.                         fwrite (value+4, vsize-4, 1, stdout);
  195.                         printf ("\"\n");
  196.                         break;
  197.                       case EAT_BINARY:
  198.                         printf ("%d bytes of binary data\n", vsize);
  199.                         break;
  200.                       case EAT_BITMAP:
  201.                         printf ("%d bytes of bitmap data\n", vsize);
  202.                         break;
  203.                       case EAT_METAFILE:
  204.                         printf ("%d bytes of metafile data\n", vsize);
  205.                         break;
  206.                       case EAT_ICON:
  207.                         printf ("%d bytes of icon data\n", vsize);
  208.                         break;
  209.                       case EAT_EA:
  210.                         printf ("%d bytes of associated data\n", vsize);
  211.                         break;
  212.                       case EAT_MVMT:
  213.                       case EAT_MVST:
  214.                       case EAT_ASN1:
  215.                         printf ("%d bytes of multivalue data\n", vsize);
  216.                         break;
  217.                       default:
  218.                         printf ("%d bytes\n", vsize);
  219.                         break;
  220.                       }
  221.                 }
  222.               else
  223.                 printf ("%d bytes\n", vsize);
  224.             }
  225.         }
  226.       _ead_destroy (ead);
  227.     }
  228. }
  229.  
  230.  
  231. static void do_put (const char *path, const char *hold)
  232. {
  233.   _ead ead;
  234.   int i;
  235.   PFEALIST pfealist;
  236.   const FEA2LIST *pfea2list;
  237.   FILE *hold_file;
  238.  
  239.   ead = _ead_create ();
  240.   if (ead == NULL)
  241.     {
  242.       perror (NULL);
  243.       exit (2);
  244.     }
  245.   if (strcmp (path, "-") == 0)
  246.     i = _ead_read (ead, NULL, fileno (stdin), 0);
  247.   else
  248.     i = _ead_read (ead, path, 0, 0);
  249.   if (i < 0)
  250.     perror (path);
  251.   else
  252.     {
  253.       hold_file = fopen (hold, "wb");
  254.       if (hold_file == NULL)
  255.         {
  256.           perror (hold);
  257.           exit (2);
  258.         }
  259.       pfea2list = _ead_get_fea2list (ead);
  260.       if (pfea2list != NULL)
  261.         {
  262.           pfealist = _ead_fea2list_to_fealist (pfea2list);
  263.           fwrite (pfealist, pfealist->cbList, 1, hold_file);
  264.           free (pfealist);
  265.         }
  266.       if (fflush (hold_file) != 0 || fclose (hold_file) != 0)
  267.         {
  268.           perror (hold);
  269.           exit (2);
  270.         }
  271.       _ead_destroy (ead);
  272.     }
  273. }
  274.  
  275.  
  276. static void do_get (const char *path, const char *hold, int merge)
  277. {
  278.   int i, wflag;
  279.   FILE *f;
  280.   long size;
  281.   PFEALIST pfealist;
  282.   PFEA2LIST pfea2list;
  283.   _ead ead;
  284.  
  285.   ead = _ead_create ();
  286.   if (ead == NULL)
  287.     {
  288.       perror (NULL);
  289.       exit (2);
  290.     }
  291.   f = fopen (hold, "rb");
  292.   if (f == NULL)
  293.     {
  294.       perror (hold);
  295.       exit (2);
  296.     }
  297.   size = filelength (fileno (f));
  298.   if (size == -1)
  299.     {
  300.       perror (hold);
  301.       exit (2);
  302.     }
  303.   if (size != 0)
  304.     {
  305.       pfealist = malloc (size);
  306.       if (pfealist == NULL)
  307.         {
  308.           fprintf (stderr, "Out of memory\n");
  309.           exit (2);
  310.         }
  311.       if (fread (pfealist, size, 1, f) != 1)
  312.         {
  313.           if (ferror (f))
  314.             perror (hold);
  315.           else
  316.             fprintf (stderr, "%s: end of file reached\n", hold);
  317.           exit (2);
  318.         }
  319.       free (pfealist);
  320.       pfea2list = _ead_fealist_to_fea2list (pfealist);
  321.       if (pfea2list == NULL)
  322.         {
  323.           perror (NULL);
  324.           exit (2);
  325.         }
  326.       if (_ead_use_fea2list (ead, pfea2list) != 0)
  327.         {
  328.           perror (NULL);
  329.           exit (2);
  330.         }
  331.       free (pfea2list);
  332.     }
  333.   fclose (f);
  334.   wflag = (merge ? _EAD_MERGE : 0);
  335.   if (strcmp (path, "-") == 0)
  336.     i = _ead_write (ead, NULL, fileno (stdout), wflag);
  337.   else
  338.     i = _ead_write (ead, path, 0, wflag);
  339.   if (i < 0)
  340.     {
  341.       perror (path);
  342.       exit (2);
  343.     }
  344.   _ead_destroy (ead);
  345. }
  346.  
  347.  
  348. static void usage (void)
  349. {
  350.   fputs ("Usage: eatool -g <datafile> <holdfile>\n", stderr);
  351.   fputs ("       eatool -m <datafile> <holdfile>\n", stderr);
  352.   fputs ("       eatool -p <datafile> <holdfile>\n", stderr);
  353.   fputs ("       eatool -d <files>\n", stderr);
  354.   fputs ("       eatool -l [-z] <files>\n", stderr);
  355.   fputs ("       eatool -a <file> <name> <value>\n", stderr);
  356.   fputs ("       eatool -r <file> <name>\n", stderr);
  357.   fputs ("Options:\n", stderr);
  358.   fputs ("  -a   Add extended attribute\n", stderr);
  359.   fputs ("  -d   Discard extended attributes\n", stderr);
  360.   fputs ("  -g   Get extended attributes from holdfile\n", stderr);
  361.   fputs ("  -m   Merge extended attributes from holdfile\n", stderr);
  362.   fputs ("  -l   List extended attributes\n", stderr);
  363.   fputs ("  -p   Put extended attributes into holdfile\n", stderr);
  364.   fputs ("  -r   Remove extended attribute\n", stderr);
  365.   fputs ("  -z   Turn on debugging output\n", stderr);
  366.   exit (1);
  367. }
  368.  
  369.  
  370. static void set_action (enum actions a)
  371. {
  372.   if (action != ACTION_NONE)
  373.     usage ();
  374.   action = a;
  375. }
  376.  
  377.  
  378. static void apply (int argc, char *argv[], void (*function)(const char *path))
  379. {
  380.   int i, j;
  381.   char **list;
  382.  
  383.   for (i = optind; i < argc; ++i)
  384.     {
  385.       list = _fnexplode (argv[i]);
  386.       if (list == NULL)
  387.         function (argv[i]);
  388.       else
  389.         {
  390.           for (j = 0; list[j] != NULL; ++j)
  391.             function (list[j]);
  392.           _fnexplodefree (list);
  393.         }
  394.     }
  395. }
  396.  
  397.  
  398. int main (int argc, char *argv[])
  399. {
  400.   int c;
  401.  
  402.   opterr = FALSE;
  403.   while ((c = getopt (argc, argv, "adglmprz")) != EOF)
  404.     {
  405.       switch (c)
  406.         {
  407.         case 'a':
  408.           set_action (ACTION_ADD);
  409.           break;
  410.         case 'd':
  411.           set_action (ACTION_DISCARD);
  412.           break;
  413.         case 'g':
  414.           set_action (ACTION_GET);
  415.           break;
  416.         case 'm':
  417.           set_action (ACTION_MERGE);
  418.           break;
  419.         case 'l':
  420.           set_action (ACTION_LIST);
  421.           break;
  422.         case 'p':
  423.           set_action (ACTION_PUT);
  424.           break;
  425.         case 'r':
  426.           set_action (ACTION_REMOVE);
  427.           break;
  428.         case 'z':
  429.           debugging = TRUE;
  430.           break;
  431.         default:
  432.           usage ();
  433.         }
  434.     }
  435.   _nls_init ();
  436.   switch (action)
  437.     {
  438.     case ACTION_ADD:
  439.       if (argc - optind != 3)
  440.         usage ();
  441.       do_add (argv[optind+0], argv[optind+1], argv[optind+2]);
  442.       break;
  443.     case ACTION_DISCARD:
  444.       apply (argc, argv, do_discard);
  445.       break;
  446.     case ACTION_GET:
  447.     case ACTION_MERGE:
  448.       if (argc - optind != 2)
  449.         usage ();
  450.       do_get (argv[optind+0], argv[optind+1], action == ACTION_MERGE);
  451.       break;
  452.     case ACTION_LIST:
  453.       apply (argc, argv, do_list);
  454.       break;
  455.     case ACTION_PUT:
  456.       if (argc - optind != 2)
  457.         usage ();
  458.       do_put (argv[optind+0], argv[optind+1]);
  459.       break;
  460.     case ACTION_REMOVE:
  461.       if (argc - optind != 2)
  462.         usage ();
  463.       do_remove (argv[optind+0], argv[optind+1]);
  464.       break;
  465.     default:
  466.       usage ();
  467.     }
  468.   return (0);
  469. }
  470.