home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / SHOWEA.ZIP / SHOWEA.C < prev    next >
Text File  |  1989-12-05  |  10KB  |  272 lines

  1. /*
  2.     SHOWEA.C    A simple demonstration program for OS/2 version 1.2
  3.                 that fetches and displays the extended attributes
  4.                 associated with a file or directory.
  5.  
  6.     Copyright (C) 1989 Ziff-Davis Communications
  7.     PC Magazine * Ray Duncan
  8.  
  9.     Compile:    cl /Zi /F 2000 showea.c
  10.                 markexe lfns showea.exe
  11.                 markexe windowcompat showea.exe
  12.  
  13.     Usage:      showea pathname
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <memory.h>
  20. #include <malloc.h>
  21.  
  22. #define dim(x) (sizeof(x)/sizeof(x[0])) // number of elements in structure
  23.  
  24. #define EAT_BINARY      0x0fffe         // Length-preceeded binary
  25. #define EAT_ASCII       0x0fffd         // Length-preceeded ASCII
  26. #define EAT_BITMAP      0x0fffb         // Length-preceeded bitmap
  27. #define EAT_METAFILE    0x0fffa         // Metafile
  28. #define EAT_ICON        0x0fff9         // Length-preceeded icon
  29. #define EAT_EA          0x0ffee         // ASCIIZ EA of associated data 
  30. #define EAT_MVMT        0x0ffdf         // Multi-value multi-type
  31. #define EAT_MVST        0x0ffde         // Multi-value single-type
  32. #define EAT_ASN1        0x0ffdd         // ASN.1 field
  33.  
  34. #define EABUF_SIZE      16384           // size of EA buffer
  35. #define MAXPATHNAME     260             // maximum length of pathname
  36. #define MAXFILENAME     255             // maximum length of filename
  37.  
  38. #define ERROR_BUFFER_OVERFLOW 111       // error code for DosQPathInfo
  39.  
  40. #define API unsigned extern far pascal  // OS/2 API function prototypes 
  41. API DosQPathInfo(char far *, unsigned, void far *, int, unsigned long);
  42.  
  43. void showea(void);                      // local function prototypes
  44. void fmtUNKNOWN(void);
  45. void fmtBINARY(void);
  46. void fmtASCII(void);
  47. void fmtBITMAP(void);
  48. void fmtMETAFILE(void);
  49. void fmtICON(void);   
  50. void fmtEA(void);  
  51. void fmtMVMT(void);   
  52. void fmtMVST(void);   
  53. void fmtASN1(void);   
  54.  
  55. struct _EA {                            // extended attribute header 
  56.         unsigned char flags;            // critical flag etc.
  57.         unsigned char nsize;            // length of EA name (without null)
  58.         unsigned vsize;                 // total size of EA value
  59.         char name[1]; } ;               // EA name and value begin here
  60.  
  61. struct _EAvalue {                       // extended attribute value 
  62.         unsigned type;                  // EA value type
  63.         unsigned size;                  // length of EA variable data
  64.         char data[1]; } ;               // actual data begins here
  65.  
  66. struct _FEAList {                       // receives extended attributes
  67.         unsigned long size;             // total size of structure
  68.         char data[1]; } ;               // extended attributes begin here
  69.  
  70. struct _EAOP {                          // used by DosQPathInfo
  71.         void far *pGEAList;             // pointer to GEAList structure         
  72.         void far *pFEAList;             // pointer to FEAList structure
  73.         unsigned long oError; } ;       // offset of error, if any
  74.  
  75. struct _EAtable {                       // lookup table of EA types
  76.         unsigned type;                  // binary type indicator
  77.         char *name;                     // descriptive text
  78.         void (*formatter)();            // formatting routine
  79.         } EAtable[] = {
  80.         0,              "unknown EA type",          fmtUNKNOWN,
  81.         EAT_BINARY,     "length-preceeded binary",  fmtBINARY,
  82.         EAT_ASCII,      "length-preceeded ASCII",   fmtASCII,
  83.         EAT_BITMAP,     "length-preceeded bitmap",  fmtBITMAP,
  84.         EAT_METAFILE,   "metafile",                 fmtMETAFILE,
  85.         EAT_ICON,       "length-preceeded icon",    fmtICON,
  86.         EAT_EA,         "associated EA data",       fmtEA,
  87.         EAT_MVMT,       "multi-value multi-type",   fmtMVMT,
  88.         EAT_MVST,       "multi-value single-type",  fmtMVST,
  89.         EAT_ASN1,       "ASN.1",                    fmtASN1, } ;
  90.  
  91. char            *fname;                 // pointer to qualified pathname
  92. struct _FEAList *FEAList;               // pointer to EA buffer
  93. struct _EA  *pEA;                       // pointer to individual EA header
  94. struct _EAvalue *pEAval;                // pointer to individual EA value
  95.  
  96. main(int argc, char *argv[])
  97. {
  98.     struct _EAOP EAOP;                  // holds pointers for DosQPathInfo
  99.     int error;                          // error code from DosQPathInfo
  100.  
  101.     if(argc != 2)                       // check command line
  102.     {
  103.         printf("\nshowea: wrong number of parameters\n");
  104.         exit(1);
  105.     }
  106.  
  107.     FEAList   = malloc(EABUF_SIZE);     // allocate EA buffer and
  108.     fname     = malloc(MAXPATHNAME);    // qualified pathname buffer
  109.  
  110.     if((FEAList==NULL)||(fname==NULL))  // exit if not enough heap 
  111.     {
  112.         printf("\nshowea: heap allocation error\n");
  113.         exit(2);
  114.     }
  115.  
  116.     EAOP.pGEAList = NULL;               // initialize EAOP components
  117.     EAOP.pFEAList = FEAList;            // and buffer to receive EAs
  118.     EAOP.oError = 0L;
  119.     FEAList->size = EABUF_SIZE - sizeof(unsigned long);
  120.  
  121.     if(error = DosQPathInfo(argv[1],    // retrieve EAs using filename
  122.                     4,                  // info level 4 = get all EAs
  123.                     &EAOP,              // buffer to receieve EAs
  124.                     sizeof(EAOP),       // size of buffer
  125.                     0L))                // reserved
  126.     {   
  127.         if(error == ERROR_BUFFER_OVERFLOW)
  128.         {
  129.             printf("\nshowea: EA buffer too small\n");
  130.             exit(3);
  131.         }
  132.  
  133.         printf("\nshowea: file or directory not found\n");
  134.         exit(4);
  135.     }
  136.                                         // display full pathname
  137.     DosQPathInfo(argv[1], 5, fname, MAXPATHNAME, 0L);
  138.  
  139.     if(FEAList->size == sizeof(unsigned long))
  140.     {
  141.         printf("\nshowea: no extended attributes found\n");
  142.         exit(5);
  143.     }
  144.  
  145.     printf("\nExtended attributes for %s:\n", strlwr(fname));
  146.     printf("\nName        Type                       Value");
  147.     
  148.     pEA = (struct _EA *) FEAList->data; // point to first EA
  149.  
  150.     while((char *) pEA < (FEAList->data+FEAList->size-sizeof(unsigned long)))
  151.     {                               
  152.         (char *) pEAval =               // point to EA value
  153.             pEA->name + pEA->nsize + 1;
  154.  
  155.         showea();                       // display this EA name & value
  156.  
  157.         (char *) pEA =                  // go to next EA
  158.             pEA->name + pEA->nsize + pEA->vsize + 1;
  159.     }
  160.     
  161.     puts("");                           // extra blank line
  162. }
  163.  
  164. /*
  165.     SHOWEA: format and display current extended attribute.
  166. */
  167. void showea(void)
  168. {
  169.     int i;                              // scratch variable
  170.  
  171.     i = findtype(pEAval->type);         // look up the EA type
  172.  
  173.     printf("\n%-10.10s  %-25.25s  ",    // display EA name, value type
  174.            pEA->name, EAtable[i].name);
  175.  
  176.     (*EAtable[i].formatter)();          // call type-specific routine
  177. }                                       // to display EA value
  178.  
  179. /*
  180.     FINDTYPE: look up extended attribute type in EAtable.
  181. */
  182. int findtype(unsigned EAtype)
  183. {
  184.     int i;                              // scratch variable
  185.  
  186.     for(i = 1; i < dim(EAtable); i++)   // skip dummy entry EAtable[0]
  187.     {
  188.         if(EAtable[i].type == EAtype)   // if we matched EA type
  189.             return(i);                  // return EAtable index
  190.     }
  191.  
  192.     return(0);                          // no match, return 0
  193. }
  194.  
  195. /*
  196.     The routines below perform formatting and output of the value
  197.     for each EA type.  In this version of the demo program only 
  198.     the length-preceded ASCII, length-preceded simple binary, and 
  199.     multi-type multi-value types are implemented.  
  200.     The remainder are dummy functions that do nothing.
  201. */
  202.  
  203. void fmtUNKNOWN(void)                   // unknown EA type
  204. {
  205.     fmtBINARY();
  206. }
  207.  
  208. void fmtBINARY(void)                    // length-preceded binary
  209. {
  210.     int i;                              // scratch variable
  211.  
  212.     for(i = 0; i < min(8, pEAval->size); i++)   // display binary data
  213.         printf("%02X ", pEAval->data[i]);   
  214.  
  215.     if(pEAval->size > 8) printf("..."); // indicate there is more
  216. }
  217.  
  218. void fmtASCII(void)                     // length-preceded ASCII string
  219. {
  220.     printf("%.*s", pEAval->size, pEAval->data);
  221. }
  222.  
  223. void fmtBITMAP(void)                    // length-preceded bitmap
  224. {
  225.     fmtBINARY();
  226. }
  227.  
  228. void fmtMETAFILE(void)                  // length-preceded metafile
  229. {
  230.     fmtBINARY();
  231. }
  232.  
  233. void fmtICON(void)                      // length-preceded icon
  234. {
  235.     fmtBINARY();
  236. }
  237.  
  238. void fmtEA(void)                        // ASCIIZ extended attribute
  239. {                                       // name of associated data
  240.     printf("%s", (char *) &pEAval->size);
  241. }
  242.  
  243. void fmtMVMT(void)                      // multi-value multi-type
  244. {
  245.     int i;                              // scratch variable
  246.     int fields;                         // number of value fields
  247.  
  248.     strcpy(pEA->name, "");              // erase EA name 
  249.     fields = *((int *)(pEAval->data));  // retrieve number of fields
  250.     (char *) pEAval =                   // point to first field
  251.         pEAval->data + sizeof(int);
  252.  
  253.     for(i = 0; i < fields; i++)         // loop across value fields
  254.     {
  255.         showea();                       // display this value field
  256.  
  257.         (char *) pEAval =               // point to next value
  258.             pEAval->data + pEAval->size; 
  259.     }
  260. }
  261.  
  262. void fmtMVST(void)                      // multi-value single-type
  263. {
  264.     return;
  265. }
  266.  
  267. void fmtASN1(void)                      // ASN.1 field
  268. {
  269.     return;
  270. }
  271.  
  272.