home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / COMMENT.ZIP / COMMENT.C next >
Text File  |  1991-11-20  |  9KB  |  261 lines

  1. /* This utility will attach a COMMENT EA to a file
  2.    Portions of this code were taken from a PC Magazine
  3.    program written by Ray Duncan - SETEA.
  4.    Those portions are copywrited by PC Magazine         */
  5.  
  6. #define INCL_DOSFILEMGR
  7. #include <os2.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <io.h>         /* needed for open, close, read, write, */
  12.                         /* filelength, and eof */
  13. #include <fcntl.h>      /* needed for open mode arguments */
  14. #include <sys\types.h> /* needed for file types */
  15. #include <sys\stat.h> /* needed for status flags */
  16. #include <malloc.h> /* needed for _memmax, malloc. and free */
  17. #include "comment.h"
  18.  
  19.  
  20. void main(int argc, char *argv[])
  21. {
  22. char szComment[80];
  23. char szFilename[255];
  24. int  iErrCode;
  25.  
  26. if (argc < 2 || argc > 3)
  27. {
  28. printf("The format of COMMENT is :\n\n");
  29. printf("COMMENT filename \" comment \" \n");
  30. printf("will add/replace a comment \n\n");
  31. printf("COMMENT filename  \n");
  32. printf("will retrieve a comment \n");
  33. }
  34.   else
  35.   {
  36.     strcpy (szFilename,argv[1]);
  37.     iErrCode = 0;
  38.     if (argc ==2)
  39.     {
  40.         iErrCode = getCommentEA(argv[1],szComment);
  41.         switch (iErrCode)
  42.         {
  43.            case 0:
  44.              strcat(szComment,"\n");
  45.              printf(szComment);
  46.              break;
  47.            case 1:
  48.              printf("No Comments on this file");
  49.              break;
  50.            case 2:
  51.              printf("Could not open file in read only mode");
  52.              break;
  53.            default:
  54.              break;
  55.         }
  56.     }
  57.     else
  58.     {
  59.         if (strlen(argv[2]) < 80)
  60.         {
  61.            iErrCode = addCommentEA(argv[1],argv[2]);
  62.            switch (iErrCode)
  63.            {
  64.               case 0:
  65.                 printf("Comment added/modified");
  66.                 break;
  67.               case 1:
  68.                 printf("Could not add the Comment Extended Attribute");
  69.                 break;
  70.               case 2:
  71.                 printf("Could not open file in read write mode");
  72.                 break;
  73.               default:
  74.                 break;
  75.            }
  76.         }
  77.         else
  78.              printf("Comment must be less than 80 characters");
  79.     }
  80.   }
  81. }
  82.  
  83. /*--------------------------------------------------------------
  84.    This function gets the COMMENT Extended Attribute and puts
  85.    it in szComment
  86.    Error Codes:
  87.      0 - ok.
  88.      1 - No COMMENT EA
  89.      2 - Could not open file in read only mode
  90.  
  91. -------------------------------------------------------*/
  92. int getCommentEA(char *szFilename, char *szComment)
  93. {
  94.     int iErrCode;
  95.     char EAnamebuf[80];                     // EA name from user
  96.     struct _EAval *pEAval;                  // scratch pointer
  97.     int handle;                             // handle for file
  98.  
  99.     if((handle = open(szFilename, O_BINARY | O_RDONLY)) == -1)
  100.                  iErrCode = 2;
  101.        else
  102.        {
  103.           strcpy(EAnamebuf, "COMMENT");
  104.           /* If no COMMENT EA then exit with a 1 */
  105.           if((pEAval = getEA(handle, EAnamebuf)) == NULL)
  106.               iErrCode = 1;
  107.           else
  108.           {
  109.               memcpy(szComment,pEAval->data,pEAval->size);
  110.               szComment[pEAval->size] = '\0';
  111.               iErrCode = 0;
  112.           }
  113.           close(handle);
  114.        }
  115. return(iErrCode);
  116. }
  117.  
  118. /*--------------------------------------------------------------
  119.    This function adds a comment to the COMMENT EA
  120.    Error Codes:
  121.      0 - COMMENT EA modified
  122.      1 - Could not add the COMMENT EA
  123.      2 - Could not open file in read/write mode
  124.  
  125. -------------------------------------------------------*/
  126. int addCommentEA(char *szFilename,char *szComment)
  127. {
  128.     int iErrCode;
  129.     char EAnamebuf[80];                     // EA name from user
  130.     char EAvalbuf[80];                      // EA value from user
  131.     int handle;                             // handle for file
  132.  
  133.     if((handle = open(szFilename, O_BINARY | O_RDWR)) == -1)
  134.                  iErrCode = 2;
  135.        else
  136.        {
  137.           strcpy(EAnamebuf, "COMMENT");
  138.           strcpy(EAvalbuf, szComment);
  139.           /* if can't set extended attribute set exit code to 4)*/
  140.           if(putEA(handle, EAnamebuf, EAvalbuf, strlen(EAvalbuf), EAT_ASCII))
  141.              iErrCode = 1;
  142.           else
  143.              iErrCode = 0;
  144.           close(handle);
  145.        }
  146. return(iErrCode);
  147. }
  148.  
  149. /*
  150.     putEA: constructs and writes an extended attribute for a previously
  151.     opened file.  Called with the handle of the file, the extended
  152.     attribute name, the EA value type, and the address and length of
  153.     the EA value field data.  Returns FALSE if extended attribute was
  154.     written successfully. Returns -1 or OS/2 errcode if function failed.
  155. */
  156. int putEA(int handle, char * eaname,
  157.           void * eavalue, unsigned eavalsize, unsigned eatype)
  158. {
  159.     struct _FEAList *pFEAList;          // misc scratch variables
  160.     struct _EA      *pEA;               // and pointers
  161.     struct _EAval   *pEAval;
  162.     struct _bEAOP    EAOP;
  163.     int errcode;
  164.  
  165.     pFEAList = malloc(FEALISTSIZE);     // allocate buffer for FEAList
  166.  
  167.     if(pFEAList == NULL) return(-1);    // bail out if no heap available
  168.  
  169.     EAOP.pFEAList = pFEAList;           // initialize contents of
  170.     EAOP.pGEAList = NULL;               // EAOP pointer structure
  171.     EAOP.oError   = 0;
  172.  
  173.     (char *) pEA = pFEAList->data;      // point to EA header field
  174.  
  175.     pEA->flags = 0;                     // construct header portion
  176. //  pEA->nsize =  strlen(eaname);       // of extended attribute
  177.     pEA->nsize = (unsigned char) strlen(eaname);  //bob
  178.     pEA->vsize = eavalsize + 4;
  179.     strcpy(pEA->name, eaname);
  180.  
  181.     (char *) pEAval =                   // calculate address of
  182.         pEA->name + pEA->nsize + 1;     // EA's value field
  183.  
  184.     pEAval->type = eatype;              // construct value portion
  185.     pEAval->size = eavalsize;           // of extended attribute
  186.     memcpy(pEAval->data, eavalue, eavalsize);
  187.  
  188.     pFEAList->size =                    // calculate size of entire
  189.         pEA->nsize + pEA->vsize + 9;    // FEAList structure
  190.  
  191.     errcode =                           // set extended attributes
  192.         DosSetFileInfo(handle,          // file handle
  193.                        2,               // info level 2 = set EAs
  194.                        (PBYTE)&EAOP,           // EAOP structure holds pointer
  195.                        sizeof(EAOP));   // to FEAList containing EAs
  196.  
  197.     free(pFEAList);                     // release working buffer
  198.     return(errcode);                    // return DosSetFileInfo status
  199. }
  200.  
  201. /*
  202.     getEA: fetches an extended attribute for a previously opened file.
  203.     Returns FALSE if the extended attribute does not exist; otherwise,
  204.     returns a pointer to the extended attribute value in a chunk of
  205.     heap memory.  The EA value is in the form of the EA type indicator,
  206.     followed by the length of variable data, followed by the data itself.
  207.     The exact format of the EA value is given by the structure _EAval.
  208.     The caller must be sure to free the memory holding the extended
  209.     attribute value after the value has been used or copied elsewhere.
  210. */
  211. struct _EAval * getEA(int handle, char * eaname)
  212. {
  213.     struct _FEAList *pFEAList = NULL;   // misc scratch variables
  214.     struct _GEAList *pGEAList = NULL;   // and pointers
  215.     struct _EA      *pEA = NULL;
  216.     struct _EAval   *pEAval = NULL;
  217.     struct _bEAOP    EAOP;
  218.  
  219.     pFEAList = malloc(FEALISTSIZE);     // allocate buffers
  220.     pGEAList = malloc(GEALISTSIZE);
  221.  
  222.     if((pFEAList == NULL) || (pGEAList == NULL))
  223.         goto errexit;                   // bail out if no heap
  224.  
  225.     EAOP.pFEAList = pFEAList;           // initialize contents of
  226.     EAOP.pGEAList = pGEAList;           // EAOP pointer structure
  227.     EAOP.oError   = 0;
  228.  
  229.     strcpy(pGEAList->GEA.name, eaname); // fill in EA name & length
  230.     pGEAList->GEA.size =  strlen(eaname);
  231.  
  232.     pFEAList->size = FEALISTSIZE;       // fill in structure sizes
  233.     pGEAList->size = pGEAList->GEA.size + 6;
  234.  
  235.     if(DosQFileInfo(handle,             // get extended attribute
  236.                     3,                  // info level 3 = get EA
  237.                     (PBYTE)&EAOP,              // EAOP struct holds pointers
  238.                     sizeof(EAOP)))      // to GEAList and FEAList
  239.         goto errexit;                   // exit if API function failed
  240.  
  241.     (char *) pEA = pFEAList->data;      // point to EA header field
  242.  
  243.     if(pEA->vsize == 0) goto errexit;   // exit if no EA value present
  244.  
  245.     if((pEAval = malloc(pEA->vsize))    // allocate space for EA value
  246.         == NULL) goto errexit;          // exit if heap is full
  247.  
  248.                                         // copy EA value to heap
  249.     memcpy(pEAval, pEA->name + pEA->nsize + 1, pEA->vsize);
  250.  
  251.     free(pFEAList);                     // release working buffers
  252.     free(pGEAList);
  253.     return(pEAval);                     // return pointer to EA value
  254.  
  255. errexit:                                // common exit point for errors
  256.     if(pFEAList != NULL) free(pFEAList);
  257.     if(pGEAList != NULL) free(pGEAList);
  258.     return(NULL);                       // NULL pointer indicates error
  259. }
  260.  
  261.