/* SHOWEA.C A simple demonstration program for OS/2 version 1.2 that fetches and displays the extended attributes associated with a file or directory. Copyright (C) 1989 Ziff-Davis Communications PC Magazine * Ray Duncan Compile: cl /Zi /F 2000 showea.c markexe lfns showea.exe markexe windowcompat showea.exe Usage: showea pathname */ #include #include #include #include #include #define dim(x) (sizeof(x)/sizeof(x[0])) // number of elements in structure #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 EA of associated data #define EAT_MVMT 0x0ffdf // Multi-value multi-type #define EAT_MVST 0x0ffde // Multi-value single-type #define EAT_ASN1 0x0ffdd // ASN.1 field #define EABUF_SIZE 16384 // size of EA buffer #define MAXPATHNAME 260 // maximum length of pathname #define MAXFILENAME 255 // maximum length of filename #define ERROR_BUFFER_OVERFLOW 111 // error code for DosQPathInfo #define API unsigned extern far pascal // OS/2 API function prototypes API DosQPathInfo(char far *, unsigned, void far *, int, unsigned long); void showea(void); // local function prototypes void fmtUNKNOWN(void); void fmtBINARY(void); void fmtASCII(void); void fmtBITMAP(void); void fmtMETAFILE(void); void fmtICON(void); void fmtEA(void); void fmtMVMT(void); void fmtMVST(void); void fmtASN1(void); 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 _EAvalue { // 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 _EAOP { // used by DosQPathInfo void far *pGEAList; // pointer to GEAList structure void far *pFEAList; // pointer to FEAList structure unsigned long oError; } ; // offset of error, if any struct _EAtable { // lookup table of EA types unsigned type; // binary type indicator char *name; // descriptive text void (*formatter)(); // formatting routine } EAtable[] = { 0, "unknown EA type", fmtUNKNOWN, EAT_BINARY, "length-preceeded binary", fmtBINARY, EAT_ASCII, "length-preceeded ASCII", fmtASCII, EAT_BITMAP, "length-preceeded bitmap", fmtBITMAP, EAT_METAFILE, "metafile", fmtMETAFILE, EAT_ICON, "length-preceeded icon", fmtICON, EAT_EA, "associated EA data", fmtEA, EAT_MVMT, "multi-value multi-type", fmtMVMT, EAT_MVST, "multi-value single-type", fmtMVST, EAT_ASN1, "ASN.1", fmtASN1, } ; char *fname; // pointer to qualified pathname struct _FEAList *FEAList; // pointer to EA buffer struct _EA *pEA; // pointer to individual EA header struct _EAvalue *pEAval; // pointer to individual EA value main(int argc, char *argv[]) { struct _EAOP EAOP; // holds pointers for DosQPathInfo int error; // error code from DosQPathInfo if(argc != 2) // check command line { printf("\nshowea: wrong number of parameters\n"); exit(1); } FEAList = malloc(EABUF_SIZE); // allocate EA buffer and fname = malloc(MAXPATHNAME); // qualified pathname buffer if((FEAList==NULL)||(fname==NULL)) // exit if not enough heap { printf("\nshowea: heap allocation error\n"); exit(2); } EAOP.pGEAList = NULL; // initialize EAOP components EAOP.pFEAList = FEAList; // and buffer to receive EAs EAOP.oError = 0L; FEAList->size = EABUF_SIZE - sizeof(unsigned long); if(error = DosQPathInfo(argv[1], // retrieve EAs using filename 4, // info level 4 = get all EAs &EAOP, // buffer to receieve EAs sizeof(EAOP), // size of buffer 0L)) // reserved { if(error == ERROR_BUFFER_OVERFLOW) { printf("\nshowea: EA buffer too small\n"); exit(3); } printf("\nshowea: file or directory not found\n"); exit(4); } // display full pathname DosQPathInfo(argv[1], 5, fname, MAXPATHNAME, 0L); if(FEAList->size == sizeof(unsigned long)) { printf("\nshowea: no extended attributes found\n"); exit(5); } printf("\nExtended attributes for %s:\n", strlwr(fname)); printf("\nName Type Value"); pEA = (struct _EA *) FEAList->data; // point to first EA while((char *) pEA < (FEAList->data+FEAList->size-sizeof(unsigned long))) { (char *) pEAval = // point to EA value pEA->name + pEA->nsize + 1; showea(); // display this EA name & value (char *) pEA = // go to next EA pEA->name + pEA->nsize + pEA->vsize + 1; } puts(""); // extra blank line } /* SHOWEA: format and display current extended attribute. */ void showea(void) { int i; // scratch variable i = findtype(pEAval->type); // look up the EA type printf("\n%-10.10s %-25.25s ", // display EA name, value type pEA->name, EAtable[i].name); (*EAtable[i].formatter)(); // call type-specific routine } // to display EA value /* FINDTYPE: look up extended attribute type in EAtable. */ int findtype(unsigned EAtype) { int i; // scratch variable for(i = 1; i < dim(EAtable); i++) // skip dummy entry EAtable[0] { if(EAtable[i].type == EAtype) // if we matched EA type return(i); // return EAtable index } return(0); // no match, return 0 } /* The routines below perform formatting and output of the value for each EA type. In this version of the demo program only the length-preceded ASCII, length-preceded simple binary, and multi-type multi-value types are implemented. The remainder are dummy functions that do nothing. */ void fmtUNKNOWN(void) // unknown EA type { fmtBINARY(); } void fmtBINARY(void) // length-preceded binary { int i; // scratch variable for(i = 0; i < min(8, pEAval->size); i++) // display binary data printf("%02X ", pEAval->data[i]); if(pEAval->size > 8) printf("..."); // indicate there is more } void fmtASCII(void) // length-preceded ASCII string { printf("%.*s", pEAval->size, pEAval->data); } void fmtBITMAP(void) // length-preceded bitmap { fmtBINARY(); } void fmtMETAFILE(void) // length-preceded metafile { fmtBINARY(); } void fmtICON(void) // length-preceded icon { fmtBINARY(); } void fmtEA(void) // ASCIIZ extended attribute { // name of associated data printf("%s", (char *) &pEAval->size); } void fmtMVMT(void) // multi-value multi-type { int i; // scratch variable int fields; // number of value fields strcpy(pEA->name, ""); // erase EA name fields = *((int *)(pEAval->data)); // retrieve number of fields (char *) pEAval = // point to first field pEAval->data + sizeof(int); for(i = 0; i < fields; i++) // loop across value fields { showea(); // display this value field (char *) pEAval = // point to next value pEAval->data + pEAval->size; } } void fmtMVST(void) // multi-value single-type { return; } void fmtASN1(void) // ASN.1 field { return; }