home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / SETEA.ZIP / GETPUTEA.C next >
Text File  |  1989-12-24  |  8KB  |  174 lines

  1. /*
  2.     GETPUTEA.C  Routines to read and write extended attributes.
  3.                 Compatible with OS/2 version 1.2.  Microsoft or
  4.                 IBM PTK header files not required.  Will need 
  5.                 modification for OS/2 2.0.
  6.  
  7.     Copyright (C) 1989 Ziff Davis Communications
  8.     PC Magazine * Ray Duncan, December 1989
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <memory.h>
  14. #include <malloc.h>
  15.                                         // EA predefined value types
  16. #define EAT_BINARY      0x0fffe         // Length-preceeded binary
  17. #define EAT_ASCII       0x0fffd         // Length-preceeded ASCII
  18. #define EAT_BITMAP      0x0fffb         // Length-preceeded bitmap
  19. #define EAT_METAFILE    0x0fffa         // Metafile
  20. #define EAT_ICON        0x0fff9         // Length-preceeded icon
  21. #define EAT_EA          0x0ffee         // ASCIIZ name of associated EA
  22. #define EAT_MVMT        0x0ffdf         // Multi-value multi-type
  23. #define EAT_MVST        0x0ffde         // Multi-value single-type
  24. #define EAT_ASN1        0x0ffdd         // ASN.1 field
  25.  
  26. #define MAXPATHNAME     260             // max length of pathname
  27. #define MAXFILENAME     255             // max length of filename
  28. #define FEALISTSIZE     1024            // arbitrary buffer size
  29. #define GEALISTSIZE     260             // arbitrary buffer size
  30.  
  31. #define API unsigned extern far pascal  // OS/2 API function prototypes 
  32. API DosQFileInfo(unsigned, unsigned, void far *, unsigned);
  33. API DosSetFileInfo(unsigned, unsigned, void far *, unsigned);
  34.  
  35. struct _EA {                            // extended attribute header 
  36.         unsigned char flags;            // critical flag etc.
  37.         unsigned char nsize;            // length of EA name (without null)
  38.         unsigned vsize;                 // total size of EA value
  39.         char name[1]; } ;               // EA name and value begin here
  40.  
  41. struct _EAval {                         // extended attribute value 
  42.         unsigned type;                  // EA value type
  43.         unsigned size;                  // length of EA variable data
  44.         char data[1]; } ;               // actual data begins here
  45.  
  46. struct _FEAList {                       // receives extended attributes
  47.         unsigned long size;             // total size of structure
  48.         char data[1]; } ;               // extended attributes begin here
  49.  
  50. struct _GEA {                           // extended attribute target name
  51.         unsigned char size;             // length of name
  52.         char name[1]; } ;               // actual name begins here
  53.  
  54. struct _GEAList {                       // holds names of EAs to get
  55.         unsigned long size;             // total size of structure
  56.         struct _GEA GEA; } ;            // name length and name text
  57.  
  58. struct _EAOP {                          // used by all EA functions
  59.         void far *pGEAList;             // pointer to GEAList structure         
  60.         void far *pFEAList;             // pointer to FEAList structure
  61.         unsigned long oError; } ;       // offset of error, if any
  62.  
  63. /*
  64.     putEA: constructs and writes an extended attribute for a previously 
  65.     opened file.  Called with the handle of the file, the extended 
  66.     attribute name, the EA value type, and the address and length of 
  67.     the EA value field data.  Returns FALSE if extended attribute was 
  68.     written successfully. Returns -1 or OS/2 errcode if function failed.
  69. */
  70. int putEA(int handle, char * eaname, 
  71.           void * eavalue, unsigned eavalsize, unsigned eatype)
  72. {
  73.     struct _FEAList *pFEAList;          // misc scratch variables
  74.     struct _EA      *pEA;               // and pointers
  75.     struct _EAval   *pEAval;
  76.     struct _EAOP    EAOP;
  77.     int errcode;
  78.  
  79.     pFEAList = malloc(FEALISTSIZE);     // allocate buffer for FEAList
  80.  
  81.     if(pFEAList == NULL) return(-1);    // bail out if no heap available    
  82.  
  83.     EAOP.pFEAList = pFEAList;           // initialize contents of 
  84.     EAOP.pGEAList = NULL;               // EAOP pointer structure
  85.     EAOP.oError   = NULL;
  86.  
  87.     (char *) pEA = pFEAList->data;      // point to EA header field     
  88.  
  89.     pEA->flags = 0;                     // construct header portion 
  90.     pEA->nsize = strlen(eaname);        // of extended attribute
  91.     pEA->vsize = eavalsize + 4;
  92.     strcpy(pEA->name, eaname);
  93.  
  94.     (char *) pEAval =                   // calculate address of 
  95.         pEA->name + pEA->nsize + 1;     // EA's value field
  96.  
  97.     pEAval->type = eatype;              // construct value portion
  98.     pEAval->size = eavalsize;           // of extended attribute
  99.     memcpy(pEAval->data, eavalue, eavalsize);
  100.  
  101.     pFEAList->size =                    // calculate size of entire
  102.         pEA->nsize + pEA->vsize + 9;    // FEAList structure
  103.  
  104.     errcode =                           // set extended attributes
  105.         DosSetFileInfo(handle,          // file handle
  106.                        2,               // info level 2 = set EAs
  107.                        &EAOP,           // EAOP structure holds pointer 
  108.                        sizeof(EAOP));   // to FEAList containing EAs
  109.  
  110.     free(pFEAList);                     // release working buffer 
  111.     return(errcode);                    // return DosSetFileInfo status
  112. }
  113.  
  114. /*
  115.     getEA: fetches an extended attribute for a previously opened file.  
  116.     Returns FALSE if the extended attribute does not exist; otherwise, 
  117.     returns a pointer to the extended attribute value in a chunk of 
  118.     heap memory.  The EA value is in the form of the EA type indicator, 
  119.     followed by the length of variable data, followed by the data itself.  
  120.     The exact format of the EA value is given by the structure _EAval.
  121.     The caller must be sure to free the memory holding the extended 
  122.     attribute value after the value has been used or copied elsewhere.
  123. */
  124. struct _EAval * getEA(int handle, char * eaname)
  125. {
  126.     struct _FEAList *pFEAList = NULL;   // misc scratch variables
  127.     struct _GEAList *pGEAList = NULL;   // and pointers
  128.     struct _EA      *pEA = NULL;
  129.     struct _EAval   *pEAval = NULL;
  130.     struct _EAOP    EAOP;
  131.  
  132.     pFEAList = malloc(FEALISTSIZE);     // allocate buffers
  133.     pGEAList = malloc(GEALISTSIZE);             
  134.  
  135.     if((pFEAList == NULL) || (pGEAList == NULL))
  136.         goto errexit;                   // bail out if no heap
  137.  
  138.     EAOP.pFEAList = pFEAList;           // initialize contents of 
  139.     EAOP.pGEAList = pGEAList;           // EAOP pointer structure
  140.     EAOP.oError   = NULL;
  141.  
  142.     strcpy(pGEAList->GEA.name, eaname); // fill in EA name & length
  143.     pGEAList->GEA.size = strlen(eaname);
  144.  
  145.     pFEAList->size = FEALISTSIZE;       // fill in structure sizes
  146.     pGEAList->size = pGEAList->GEA.size + 6;    
  147.  
  148.     if(DosQFileInfo(handle,             // get extended attribute
  149.                     3,                  // info level 3 = get EA
  150.                     &EAOP,              // EAOP struct holds pointers
  151.                     sizeof(EAOP)))      // to GEAList and FEAList
  152.         goto errexit;                   // exit if API function failed
  153.  
  154.     (char *) pEA = pFEAList->data;      // point to EA header field
  155.  
  156.     if(pEA->vsize == 0) goto errexit;   // exit if no EA value present
  157.  
  158.     if((pEAval = malloc(pEA->vsize))    // allocate space for EA value
  159.         == NULL) goto errexit;          // exit if heap is full
  160.  
  161.                                         // copy EA value to heap
  162.     memcpy(pEAval, pEA->name + pEA->nsize + 1, pEA->vsize);
  163.  
  164.     free(pFEAList);                     // release working buffers
  165.     free(pGEAList);
  166.     return(pEAval);                     // return pointer to EA value
  167.  
  168. errexit:                                // common exit point for errors
  169.     if(pFEAList != NULL) free(pFEAList);
  170.     if(pGEAList != NULL) free(pGEAList);
  171.     return(NULL);                       // NULL pointer indicates error
  172. }
  173.  
  174.