home *** CD-ROM | disk | FTP | other *** search
- /*
- GETPUTEA.C Routines to read and write extended attributes.
- Compatible with OS/2 version 1.2. Microsoft or
- IBM PTK header files not required. Will need
- modification for OS/2 2.0.
-
- Copyright (C) 1989 Ziff Davis Communications
- PC Magazine * Ray Duncan, December 1989
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <memory.h>
- #include <malloc.h>
- // EA predefined value types
- #define EAT_BINARY 0x0fffe // Length-preceeded binary
- #define EAT_ASCII 0x0fffd // Length-preceeded ASCII
- #define EAT_BITMAP 0x0fffb // Length-preceeded bitmap
- #define EAT_METAFILE 0x0fffa // Metafile
- #define EAT_ICON 0x0fff9 // Length-preceeded icon
- #define EAT_EA 0x0ffee // ASCIIZ name of associated EA
- #define EAT_MVMT 0x0ffdf // Multi-value multi-type
- #define EAT_MVST 0x0ffde // Multi-value single-type
- #define EAT_ASN1 0x0ffdd // ASN.1 field
-
- #define MAXPATHNAME 260 // max length of pathname
- #define MAXFILENAME 255 // max length of filename
- #define FEALISTSIZE 1024 // arbitrary buffer size
- #define GEALISTSIZE 260 // arbitrary buffer size
-
- #define API unsigned extern far pascal // OS/2 API function prototypes
- API DosQFileInfo(unsigned, unsigned, void far *, unsigned);
- API DosSetFileInfo(unsigned, unsigned, void far *, unsigned);
-
- struct _EA { // extended attribute header
- unsigned char flags; // critical flag etc.
- unsigned char nsize; // length of EA name (without null)
- unsigned vsize; // total size of EA value
- char name[1]; } ; // EA name and value begin here
-
- struct _EAval { // extended attribute value
- unsigned type; // EA value type
- unsigned size; // length of EA variable data
- char data[1]; } ; // actual data begins here
-
- struct _FEAList { // receives extended attributes
- unsigned long size; // total size of structure
- char data[1]; } ; // extended attributes begin here
-
- struct _GEA { // extended attribute target name
- unsigned char size; // length of name
- char name[1]; } ; // actual name begins here
-
- struct _GEAList { // holds names of EAs to get
- unsigned long size; // total size of structure
- struct _GEA GEA; } ; // name length and name text
-
- struct _EAOP { // used by all EA functions
- void far *pGEAList; // pointer to GEAList structure
- void far *pFEAList; // pointer to FEAList structure
- unsigned long oError; } ; // offset of error, if any
-
- /*
- putEA: constructs and writes an extended attribute for a previously
- opened file. Called with the handle of the file, the extended
- attribute name, the EA value type, and the address and length of
- the EA value field data. Returns FALSE if extended attribute was
- written successfully. Returns -1 or OS/2 errcode if function failed.
- */
- int putEA(int handle, char * eaname,
- void * eavalue, unsigned eavalsize, unsigned eatype)
- {
- struct _FEAList *pFEAList; // misc scratch variables
- struct _EA *pEA; // and pointers
- struct _EAval *pEAval;
- struct _EAOP EAOP;
- int errcode;
-
- pFEAList = malloc(FEALISTSIZE); // allocate buffer for FEAList
-
- if(pFEAList == NULL) return(-1); // bail out if no heap available
-
- EAOP.pFEAList = pFEAList; // initialize contents of
- EAOP.pGEAList = NULL; // EAOP pointer structure
- EAOP.oError = NULL;
-
- (char *) pEA = pFEAList->data; // point to EA header field
-
- pEA->flags = 0; // construct header portion
- pEA->nsize = strlen(eaname); // of extended attribute
- pEA->vsize = eavalsize + 4;
- strcpy(pEA->name, eaname);
-
- (char *) pEAval = // calculate address of
- pEA->name + pEA->nsize + 1; // EA's value field
-
- pEAval->type = eatype; // construct value portion
- pEAval->size = eavalsize; // of extended attribute
- memcpy(pEAval->data, eavalue, eavalsize);
-
- pFEAList->size = // calculate size of entire
- pEA->nsize + pEA->vsize + 9; // FEAList structure
-
- errcode = // set extended attributes
- DosSetFileInfo(handle, // file handle
- 2, // info level 2 = set EAs
- &EAOP, // EAOP structure holds pointer
- sizeof(EAOP)); // to FEAList containing EAs
-
- free(pFEAList); // release working buffer
- return(errcode); // return DosSetFileInfo status
- }
-
- /*
- getEA: fetches an extended attribute for a previously opened file.
- Returns FALSE if the extended attribute does not exist; otherwise,
- returns a pointer to the extended attribute value in a chunk of
- heap memory. The EA value is in the form of the EA type indicator,
- followed by the length of variable data, followed by the data itself.
- The exact format of the EA value is given by the structure _EAval.
- The caller must be sure to free the memory holding the extended
- attribute value after the value has been used or copied elsewhere.
- */
- struct _EAval * getEA(int handle, char * eaname)
- {
- struct _FEAList *pFEAList = NULL; // misc scratch variables
- struct _GEAList *pGEAList = NULL; // and pointers
- struct _EA *pEA = NULL;
- struct _EAval *pEAval = NULL;
- struct _EAOP EAOP;
-
- pFEAList = malloc(FEALISTSIZE); // allocate buffers
- pGEAList = malloc(GEALISTSIZE);
-
- if((pFEAList == NULL) || (pGEAList == NULL))
- goto errexit; // bail out if no heap
-
- EAOP.pFEAList = pFEAList; // initialize contents of
- EAOP.pGEAList = pGEAList; // EAOP pointer structure
- EAOP.oError = NULL;
-
- strcpy(pGEAList->GEA.name, eaname); // fill in EA name & length
- pGEAList->GEA.size = strlen(eaname);
-
- pFEAList->size = FEALISTSIZE; // fill in structure sizes
- pGEAList->size = pGEAList->GEA.size + 6;
-
- if(DosQFileInfo(handle, // get extended attribute
- 3, // info level 3 = get EA
- &EAOP, // EAOP struct holds pointers
- sizeof(EAOP))) // to GEAList and FEAList
- goto errexit; // exit if API function failed
-
- (char *) pEA = pFEAList->data; // point to EA header field
-
- if(pEA->vsize == 0) goto errexit; // exit if no EA value present
-
- if((pEAval = malloc(pEA->vsize)) // allocate space for EA value
- == NULL) goto errexit; // exit if heap is full
-
- // copy EA value to heap
- memcpy(pEAval, pEA->name + pEA->nsize + 1, pEA->vsize);
-
- free(pFEAList); // release working buffers
- free(pGEAList);
- return(pEAval); // return pointer to EA value
-
- errexit: // common exit point for errors
- if(pFEAList != NULL) free(pFEAList);
- if(pGEAList != NULL) free(pGEAList);
- return(NULL); // NULL pointer indicates error
- }
-