home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / g / gtak212.zip / LIBX / os2ea_ld.c < prev    next >
C/C++ Source or Header  |  1993-02-24  |  8KB  |  342 lines

  1. /*
  2.  * $Id: os2ea_ld.c,v 1.13 1993/01/15 12:29:27 AK Exp $
  3.  *
  4.  * Extended Attribute Management for OS/2.
  5.  * - Load/Store EAs.
  6.  *
  7.  * A.Kaiser    Mai 91
  8.  *
  9.  * $Log: os2ea_ld.c,v $
  10.  * Revision 1.13  1993/01/15  12:29:27  AK
  11.  * - Better handling of empty EA list.
  12.  * - Clear EA buffer before use to clear alignment gaps.
  13.  *
  14.  * Revision 1.12  1992/11/23  14:02:49  AK
  15.  * OS/2 2.0 SP Bug
  16.  *
  17.  * Revision 1.11  1992/10/26  12:28:38  ak
  18.  * Bugfix. Some IFSs return a EA cbList value > of 64K even if no EAs are
  19.  * present. Now cnt is checked for 0 after DosEnumAttribute.
  20.  *
  21.  * Revision 1.10  1992/07/24  11:49:38  ak
  22.  * Fixed memory leak: lists were not freed when load_ea returned 0.
  23.  *
  24.  * OS/2 2.0 ea buffer not contains a magic number field.
  25.  * Type of EA buffer changed from FEAList to EABuf.
  26.  *
  27.  * Revision 1.9  1992/04/21  12:32:49  ak
  28.  * EMX 0.8c.
  29.  *
  30.  * Revision 1.8  1992/04/07  17:23:24  ak
  31.  * OS/2 2.0 bugfix.
  32.  *
  33.  * Revision 1.7  1992/03/05  20:28:26  ak
  34.  * Bugfix.
  35.  *
  36.  * Revision 1.6  1992/02/26  20:53:40  ak
  37.  * OS/2 2.0.
  38.  *
  39.  * Revision 1.5  1992/02/14  18:40:33  ak
  40.  * *** empty log message ***
  41.  *
  42.  * Revision 1.4  1992/01/03  14:37:19  ak
  43.  * Header -> Id
  44.  *
  45.  * Revision 1.3  1992/01/03  14:03:45  ak
  46.  * Zortech fixes & updates.
  47.  *
  48.  * Revision 1.2  1991/12/12  20:21:14  ak
  49.  * RCSID fixes.
  50.  * mk(s)temp fixed.
  51.  *
  52.  * Revision 1.1.1.1  1991/12/12  17:15:22  ak
  53.  * Initial checkin of server source, modified to contain RCS IDs.
  54.  *
  55.  * Revision 1.1  1991/12/12  17:15:17  ak
  56.  * Initial revision
  57.  *
  58.  */
  59. #ifdef OS2
  60.  
  61. static char *rcsid = "$Id: os2ea_ld.c,v 1.13 1993/01/15 12:29:27 AK Exp $";
  62.  
  63. /* do not use QueryPathInfo for EA size, cbList is invalid in ServicePack */
  64. #define OS2BUG_InvalidPathInfo    1
  65. #define AcceptZeroMagic        1    /* for GTAK 2.10 bug */
  66.  
  67. #include <string.h>
  68. #include <stdlib.h>
  69. #include <limits.h>
  70. #define INCL_DOSFILEMGR
  71. #include <os2.h>
  72. #include <errno.h>
  73. #include <os2eattr.h>
  74.  
  75. #if OS2 >= 2
  76.  #ifndef _fmalloc
  77.   #define _fmalloc    malloc
  78.   #define _frealloc    realloc
  79.   #define _ffree    free
  80.   #define _fmemcpy    memcpy
  81.   #define _fmemcmp    memcmp
  82.  #endif
  83. #elif defined(__ZTC__)
  84.  #include <ztc.h>
  85. #else
  86.  #include <malloc.h>
  87.  #include <memory.h>
  88. #endif
  89.  
  90. #if OS2 >= 2
  91.   struct EABuf {
  92.       long    magic;
  93.       FEAList    ea;
  94.   };
  95. #else
  96.   struct EABuf {
  97.       FEAList    ea;
  98.   };
  99. #endif
  100.  
  101. static pEABuf
  102. load_ea(char *name, int file)
  103. {
  104. #if OS2 >= 2
  105.     FILESTATUS4    finfo;
  106. #else
  107.     FILESTATUS2    finfo;
  108. #endif
  109.     pEABuf        pea = 0;
  110.     int        rc;
  111.     ULONG        cnt;
  112.     pFEAList    feaList;
  113.     pFEA        pfea;
  114.     unsigned    length;
  115.     pGEA        pgea;
  116.     pGEAList    geaList = 0;
  117.     EAOPData    eaop;
  118.     pENA        pena;
  119.     PBYTE        pbyte;
  120.  
  121.     /*
  122.      * Get size of EA list.
  123.      */
  124. #if OS2 >= 2
  125.     rc = name ? DosQueryPathInfo((PSZ)name, FIL_QUERYEASIZE, (PBYTE)&finfo, sizeof finfo)
  126.           : DosQueryFileInfo(file, FIL_QUERYEASIZE, (PBYTE)&finfo, sizeof finfo);
  127. #else
  128.     rc = name ? DosQPathInfo((PSZ)name, FIL_QUERYEASIZE, (PBYTE)&finfo, sizeof finfo, 0L)
  129.           : DosQFileInfo(file, FIL_QUERYEASIZE, (PBYTE)&finfo, sizeof finfo);
  130. #endif
  131.     if (rc) goto error;
  132. #if OS2BUG_InvalidPathInfo
  133.     if (finfo.cbList < 65535)
  134.         finfo.cbList = 65535;
  135. #endif
  136.  
  137.     /*
  138.      * Allocate buffers.
  139.      */
  140. #if OS2 >= 2
  141.     if (finfo.cbList == 0) return 0;
  142.     length = 2 * finfo.cbList;
  143.     if ((geaList = _fmalloc(length)) == 0) goto nomem;
  144.     if ((pea = _fmalloc(sizeof(long) + length)) == 0) goto nomem;
  145.     pea->magic = EAMagic2;
  146.     feaList = &pea->ea;
  147. #else
  148.     if (finfo.cbList == 0 || finfo.cbList >= UINT_MAX) return 0;
  149.     length = finfo.cbList;
  150.     if ((geaList = _fmalloc(length)) == 0) goto nomem;
  151.     if ((pea = _fmalloc(length)) == 0) goto nomem;
  152.     feaList = &pea->ea;
  153. #endif
  154.  
  155.     /*
  156.      * Get EA names to buffer <feaList>.
  157.      */
  158.     cnt = -1L;
  159. #if OS2 >= 2
  160.     if (name) rc = DosEnumAttribute(1, (PVOID)name,
  161.             1L, feaList, length, &cnt, 1);
  162.     else      rc = DosEnumAttribute(0, (PVOID)&file,
  163.             1L, feaList, length, &cnt, 1);
  164. #else
  165.     if (name) rc = DosEnumAttribute(ENUMEA_REFTYPE_PATH,    (PVOID)name,
  166.             1L, feaList, length, &cnt, ENUMEA_LEVEL_NO_VALUE, 0L);
  167.     else      rc = DosEnumAttribute(ENUMEA_REFTYPE_FHANDLE, (PVOID)&file,
  168.             1L, feaList, length, &cnt, ENUMEA_LEVEL_NO_VALUE, 0L);
  169. #endif
  170.     if (rc) goto error;
  171.     if (cnt == 0) goto error;
  172.  
  173.     /*
  174.      * Convert EA enumeration list to <geaList>.
  175.      */
  176. #if OS2 >= 2
  177.     pena = (pENA)feaList;
  178.     pgea = geaList->list;
  179.     while (cnt--) {
  180.         unsigned n = pena->cbName + 1;
  181.         PBYTE p2 = &pgea->szName[n];
  182.         if ((unsigned)p2 & 3)
  183.             p2 += 4 - ((unsigned)p2 & 3);
  184.         pgea->cbName = pena->cbName;
  185.         _fmemcpy(pgea->szName, pena->szName, n);
  186.         pgea->oNextEntryOffset = cnt ? p2 - (PBYTE)pgea : 0;
  187.         pgea = (pGEA) p2;
  188.         pena = (pENA) ((PBYTE)pena + pena->oNextEntryOffset);
  189.     }
  190.     geaList->cbList = (PBYTE)pgea - (PBYTE)geaList;
  191. #else
  192.     pena = (pENA)feaList;
  193.     pbyte = (PBYTE)geaList->list;
  194.     while (cnt--) {
  195.         unsigned n = pena->cbName;
  196.         *pbyte++ = n++;
  197.         _fmemcpy(pbyte, pena->szName, n);
  198.         pbyte += n;
  199.         pena = (pENA)&pena->szName[n];
  200.     }
  201.     geaList->cbList = pbyte - (PBYTE)geaList;
  202. #endif
  203.  
  204. #if OS2 >= 2
  205.     /*
  206.      * Initialize alignment gaps with 0.
  207.      */
  208.     memset(&pea->ea, 0, length);
  209. #endif
  210.  
  211.     /*
  212.      * Get EA name & value list to <feaList>.
  213.      */
  214.     feaList->cbList = length;
  215. #if OS2 >= 2
  216.     eaop.fpGEA2List = geaList;
  217.     eaop.fpFEA2List = feaList;
  218.     if ( name && (rc = DosQueryPathInfo((PSZ)name, FIL_QUERYEASFROMLIST,
  219.         (PBYTE)&eaop, sizeof(EAOPData))) != 0
  220.      || !name && (rc = DosQueryFileInfo(file,      FIL_QUERYEASFROMLIST,
  221.         (PBYTE)&eaop, sizeof(EAOPData))) != 0)
  222.              goto error;
  223. #else
  224.     eaop.fpGEAList = geaList;
  225.     eaop.fpFEAList = feaList;
  226.     if ( name && (rc = DosQPathInfo((PSZ)name, FIL_QUERYEASFROMLIST,
  227.         (PBYTE)&eaop, sizeof(EAOPData), 0L)) != 0
  228.      || !name && (rc = DosQFileInfo(file,      FIL_QUERYEASFROMLIST,
  229.         (PBYTE)&eaop, sizeof(EAOPData))) != 0)
  230.              goto error;
  231. #endif
  232.  
  233.     _ffree(geaList);
  234.  
  235.     return pea;
  236.  
  237. error:    errno = rc;
  238.     if (geaList) _ffree(geaList);
  239.     if (pea) _ffree(pea);
  240.     return 0;
  241.  
  242. nomem:    errno = ENOMEM;
  243.     if (geaList) _ffree(geaList);
  244.     if (pea) _ffree(pea);
  245.     return 0;
  246. }
  247.  
  248. pEABuf
  249. ea_load(char *name)
  250. {
  251.     return load_ea(name, 0);
  252. }
  253.  
  254. pEABuf
  255. ea_fload(unsigned file)
  256. {
  257.     return load_ea(0, file);
  258. }
  259.  
  260. int
  261. ea_store(pEABuf pea, char *name)
  262. {
  263.     EAOPData    eaop;
  264.     int        rc;
  265.     static GEAList    geal = { 1 };
  266.  
  267. #if AcceptZeroMagic
  268.     if (!TestEAMagic(pea) && pea->magic != 0) {
  269. #else
  270.     if (!TestEAMagic(pea)) {
  271. #endif
  272.         errno = 255;    /* ERROR_EA_LIST_INCONSISTENT */
  273.         return -1;
  274.     }
  275.  
  276. #if OS2 >= 2
  277.     eaop.fpGEA2List = &geal;    /* dummy, unused */
  278.     eaop.fpFEA2List = &pea->ea;
  279.     if ((rc = DosSetPathInfo((PSZ)name, FIL_QUERYEASIZE,
  280.             (PBYTE)&eaop, sizeof(EAOPData), 0)) != 0) {
  281. #else
  282.     eaop.fpGEAList = &geal;        /* dummy, unused */
  283.     eaop.fpFEAList = &pea->ea;
  284.     if ((rc = DosSetPathInfo((PSZ)name, FIL_QUERYEASIZE,
  285.             (PBYTE)&eaop, sizeof(EAOPData), 0, 0L)) != 0) {
  286. #endif
  287.         errno = rc;
  288.         return -1;
  289.     }
  290.     return 0;
  291. }
  292.  
  293. int
  294. ea_fstore(pEABuf pea, unsigned file)
  295. {
  296.     EAOPData    eaop;
  297.     int        rc;
  298.     static GEAList    geal = { 1 };
  299.  
  300. #if OS2 >= 2
  301.     eaop.fpGEA2List = &geal;    /* dummy, unused */
  302.     eaop.fpFEA2List = &pea->ea;
  303. #else
  304.     eaop.fpGEAList = &geal;        /* dummy, unused */
  305.     eaop.fpFEAList = &pea->ea;
  306. #endif
  307.     if ((rc = DosSetFileInfo(file, FIL_QUERYEASIZE,
  308.             (PBYTE)&eaop, sizeof(EAOPData))) != 0) {
  309.         errno = rc;
  310.         return -1;
  311.     }
  312.     return 0;
  313. }
  314.  
  315. pEABuf
  316. ea_alloc(unsigned long size)
  317. {
  318.     pEABuf pea;
  319.     if (size < sizeof(ULONG))
  320.         size = sizeof(ULONG);
  321.     if (size != (size_t)size)
  322.         return 0;
  323. #if OS2 >= 2
  324.     if ((pea = _fmalloc((size_t)(sizeof(long) + size))) == 0)
  325.         return 0;
  326.     pea->magic = EAMagic2;
  327. #else
  328.     if ((pea = _fmalloc((size_t)size)) == 0)
  329.         return 0;
  330. #endif
  331.     pea->ea.cbList = size;
  332.     return pea;
  333. }
  334.  
  335. void
  336. ea_free(pEABuf pea)
  337. {
  338.     _ffree(pea);
  339. }
  340.  
  341. #endif
  342.