/*
    SETEA.C     Assigns an ASCII extended attribute to a file.  
                Demonstrates use of the getEA() and putEA() 
                subroutines in GETPUTEA.C.

                This program does not require Microsoft or IBM 
                Toolkit header files, but must be built using LINK
                and DOSCALLS.LIB from retail OS/2 version 1.2.  

                Warning: EA names and values are case sensitive.

    Copyright (C) 1989 Ziff Davis Communications
    PC Magazine * Ray Duncan, December 1989

    Compile:    cl -c /Zi setea.c
                cl -c /Zi getputea.c
                link setea+getputea,setea,,doscalls,setea.def;

    Usage:      setea filename.exe EAname=EAvalue

    Examples:   setea myprog.exe .TYPE=Executable
                setea myfile.txt ".TYPE=Plain Text"
*/

#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.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 API unsigned extern far pascal      // OS/2 API function prototypes 
API DosQPathInfo(void far *, unsigned, char far *, int, unsigned long);

struct _EAval * getEA(int, char *);         // GETPUTEA.C prototypes
int putEA(int, char *, void *, unsigned, unsigned);

struct _EAval {                             // extended attribute value 
        unsigned type;                      // EA value type
        unsigned size;                      // length of EA variable data
        char data[1]; } ;                   // actual data begins here

main(int argc, char *argv[])
{
    char EAnamebuf[80];                     // EA name from user
    char EAvalbuf[80];                      // EA value from user
    char pathnamebuf[MAXPATHNAME];          // fully qualified pathname
    struct _EAval *pEAval;                  // scratch pointer
    int handle;                             // handle for file  

    if(argc != 3)                           // check command line
    {
        printf("\nUsage:     setea filename.exe EAname=EAvalue\n");
        printf("\nWarning:   Extended attribute names and values");
        printf("\n           are case sensitive.  Use quotes to");
        printf("\n           embed blanks in EA value.\n");
        printf("\nExamples:  setea myprog.exe .TYPE=Executable");
        printf("\n           setea myfile.txt \".TYPE=Plain Text\"\n");
        exit(1);
    }
                                            // open the file
    if((handle = open(argv[1], O_BINARY | O_RDWR)) == -1)
    {
        printf("\nsetea: file not found or read-only\n");
        exit(2);
    }
                                            // get fully qualified pathname
    if(DosQPathInfo(argv[1], 5, pathnamebuf, MAXPATHNAME, 0L))
    {
        printf("\nsetea: can't qualify pathname\n");
        exit(3);
    }
                                            // parse EA name and value
    strcpy(EAnamebuf, strtok(argv[2], " =\x0a"));
    strcpy(EAvalbuf, strtok(NULL, "\x0a"));

                                            // write new EA to disk
    if(putEA(handle, EAnamebuf, EAvalbuf, strlen(EAvalbuf), EAT_ASCII))
    {
        printf("\nsetea: can't set extended attribute!\n");
        exit(4);
    }
                                            // read new EA back again
    if((pEAval = getEA(handle, EAnamebuf)) == NULL)
    {
        printf("\nsetea: can't reread extended attribute!\n");
        exit(5);
    }
                                            // display EA name and value
    printf("\nFile name:\t %s\nEA name:\t %s\nEA value:\t %.*s\n",
           strlwr(pathnamebuf), EAnamebuf, pEAval->size, pEAval->data);

    free(pEAval);                           // release heap memory
}

