os2acl.c
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:9k
源码类别:

压缩解压

开发平台:

MultiPlatform

  1. /* os2acl.c - access to OS/2 (LAN Server) ACLs
  2.  *
  3.  * Author:  Kai Uwe Rommel <rommel@ars.de>
  4.  * Created: Mon Aug 08 1994
  5.  *
  6.  * This code is in the public domain.
  7.  */
  8. /*
  9.  * supported 32-bit compilers:
  10.  * - emx+gcc
  11.  * - IBM C Set++ 2.1 or newer
  12.  * - Watcom C/C++ 10.0 or newer
  13.  *
  14.  * supported 16-bit compilers:
  15.  * - MS C 6.00A
  16.  * - Watcom C/C++ 10.0 or newer
  17.  *
  18.  * supported OS/2 LAN environments:
  19.  * - IBM LAN Server/Requester 3.0, 4.0 and 5.0 (Warp Server)
  20.  * - IBM Peer 1.0 (Warp Connect)
  21.  */
  22. #ifdef KUR
  23.    static char *rcsid =
  24.    "$Id: os2acl.c,v 1.3 1996/04/03 19:18:27 rommel Exp rommel $";
  25.    static char *rcsrev = "$Revision: 1.3 $";
  26. #endif
  27. /*
  28.  * $Log: os2acl.c,v $
  29.  * Revision 1.3  1996/04/03 19:18:27  rommel
  30.  * minor fixes
  31.  *
  32.  * Revision 1.2  1996/03/30 22:03:52  rommel
  33.  * avoid frequent dynamic allocation for every call
  34.  * streamlined code
  35.  *
  36.  * Revision 1.1  1996/03/30 09:35:00  rommel
  37.  * Initial revision
  38.  *
  39.  */
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <ctype.h>
  44. #include <malloc.h>
  45. #define INCL_NOPM
  46. #define INCL_DOS
  47. #define INCL_DOSERRORS
  48. #include <os2.h>
  49. #include "os2/os2acl.h"
  50. #define UNLEN 20
  51. #if defined(__WATCOMC__) && defined(__386__) && !defined(__32BIT__)
  52. #define __32BIT__
  53. #endif
  54. #ifdef __32BIT__
  55. typedef ULONG U_INT;
  56. #ifdef __EMX__
  57. #define PSTR16 _far16ptr
  58. #define PTR16(x) _emx_32to16(x)
  59. #else /* other 32-bit */
  60. #define PSTR16 PCHAR16
  61. #define PTR16(x) ((PCHAR16)(x))
  62. #endif
  63. #else /* 16-bit */
  64. typedef USHORT U_INT;
  65. #define PSTR16 PSZ
  66. #define PTR16(x) (x)
  67. #endif
  68. typedef struct access_list
  69. {
  70.   char acl_ugname[UNLEN+1];
  71.   char acl_pad;
  72.   USHORT acl_access;
  73. }
  74. ACCLIST;
  75. typedef struct access_info
  76. {
  77.   PSTR16 acc_resource_name;
  78.   USHORT acc_attr;
  79.   USHORT acc_count;
  80. }
  81. ACCINFO;
  82. static ACCINFO *ai;
  83. static char *path, *data;
  84. #ifdef __32BIT__
  85. #ifdef __EMX__
  86. static USHORT (APIENTRY *_NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
  87.   USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
  88. static USHORT (APIENTRY *_NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
  89.   USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
  90. static USHORT (APIENTRY *_NetAccessAdd)(PSZ pszServer,
  91.   USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
  92. USHORT NetAccessGetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
  93.                         PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail)
  94. {
  95.   return (USHORT)
  96.           (_THUNK_PROLOG (4+4+2+4+2+4);
  97.            _THUNK_FLAT (pszServer);
  98.            _THUNK_FLAT (pszResource);
  99.            _THUNK_SHORT (sLevel);
  100.            _THUNK_FLAT (pbBuffer);
  101.            _THUNK_SHORT (cbBuffer);
  102.            _THUNK_FLAT (pcbTotalAvail);
  103.            _THUNK_CALLI (_emx_32to16(_NetAccessGetInfo)));
  104. }
  105. USHORT NetAccessSetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
  106.                         PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum)
  107. {
  108.   return (USHORT)
  109.           (_THUNK_PROLOG (4+4+2+4+2+2);
  110.            _THUNK_FLAT (pszServer);
  111.            _THUNK_FLAT (pszResource);
  112.            _THUNK_SHORT (sLevel);
  113.            _THUNK_FLAT (pbBuffer);
  114.            _THUNK_SHORT (cbBuffer);
  115.            _THUNK_SHORT (sParmNum);
  116.            _THUNK_CALLI (_emx_32to16(_NetAccessSetInfo)));
  117. }
  118. USHORT NetAccessAdd(PSZ pszServer, USHORT sLevel,
  119.                     PVOID pbBuffer, USHORT cbBuffer)
  120. {
  121.   return (USHORT)
  122.           (_THUNK_PROLOG (4+2+4+2);
  123.            _THUNK_FLAT (pszServer);
  124.            _THUNK_SHORT (sLevel);
  125.            _THUNK_FLAT (pbBuffer);
  126.            _THUNK_SHORT (cbBuffer);
  127.            _THUNK_CALLI (_emx_32to16(_NetAccessAdd)));
  128. }
  129. #else /* other 32-bit */
  130. APIRET16 (* APIENTRY16 NetAccessGetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
  131.   USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, PVOID16 pcbTotalAvail);
  132. APIRET16 (* APIENTRY16 NetAccessSetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
  133.   USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, USHORT sParmNum);
  134. APIRET16 (* APIENTRY16 NetAccessAdd)(PCHAR16 pszServer,
  135.   USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer);
  136. #define _NetAccessGetInfo NetAccessGetInfo
  137. #define _NetAccessSetInfo NetAccessSetInfo
  138. #define _NetAccessAdd NetAccessAdd
  139. #if !defined(__IBMC__) || !defined(__TILED__)
  140. #define _tmalloc malloc
  141. #define _tfree free
  142. #endif
  143. #endif
  144. #else /* 16-bit */
  145. USHORT (APIENTRY *NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
  146.   USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
  147. USHORT (APIENTRY *NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
  148.   USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
  149. USHORT (APIENTRY *NetAccessAdd)(PSZ pszServer,
  150.   USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
  151. #define _NetAccessGetInfo NetAccessGetInfo
  152. #define _NetAccessSetInfo NetAccessSetInfo
  153. #define _NetAccessAdd NetAccessAdd
  154. #define _tmalloc malloc
  155. #define _tfree free
  156. #define DosQueryProcAddr(handle, ord, name, funcptr) 
  157.         DosGetProcAddr(handle, name, funcptr)
  158. #define DosQueryCurrentDir DosQCurDir
  159. #define DosQueryCurrentDisk DosQCurDisk
  160. #endif
  161. static BOOL acl_init(void)
  162. {
  163.   static BOOL initialized, netapi_avail;
  164.   HMODULE netapi;
  165.   char buf[256];
  166.   if (initialized)
  167.     return netapi_avail;
  168.   initialized = TRUE;
  169.   if (DosLoadModule(buf, sizeof(buf), "NETAPI", &netapi))
  170.     return FALSE;
  171.   if (DosQueryProcAddr(netapi, 0, "NETACCESSGETINFO", (PFN *) &_NetAccessGetInfo) ||
  172.       DosQueryProcAddr(netapi, 0, "NETACCESSSETINFO", (PFN *) &_NetAccessSetInfo) ||
  173.       DosQueryProcAddr(netapi, 0, "NETACCESSADD", (PFN *) &_NetAccessAdd))
  174.     return FALSE;
  175. #if defined(__WATCOMC__) && defined(__386__)
  176.   NetAccessGetInfo = (PVOID) (ULONG) (PVOID16) NetAccessGetInfo;
  177.   NetAccessSetInfo = (PVOID) (ULONG) (PVOID16) NetAccessSetInfo;
  178.   NetAccessAdd     = (PVOID) (ULONG) (PVOID16) NetAccessAdd;
  179. #endif
  180.   if ((path = _tmalloc(CCHMAXPATH)) == NULL)
  181.     return FALSE;
  182.   if ((data = _tmalloc(ACL_BUFFERSIZE)) == NULL)
  183.     return FALSE;
  184.   if ((ai = _tmalloc(sizeof(ACCINFO))) == NULL)
  185.     return -1;
  186.   netapi_avail = TRUE;
  187.   return netapi_avail;
  188. }
  189. static void acl_mkpath(char *buffer, const char *source)
  190. {
  191.   char *ptr;
  192.   static char cwd[CCHMAXPATH];
  193.   static U_INT cwdlen;
  194.   U_INT cdrive;
  195.   ULONG drivemap;
  196.   if (isalpha(source[0]) && source[1] == ':')
  197.     buffer[0] = 0; /* fully qualified names */
  198.   else
  199.   {
  200.     if (cwd[0] == 0)
  201.     {
  202.       DosQueryCurrentDisk(&cdrive, &drivemap);
  203.       cwd[0] = (char)(cdrive + '@');
  204.       cwd[1] = ':';
  205.       cwd[2] = '\';
  206.       cwdlen = sizeof(cwd) - 3;
  207.       DosQueryCurrentDir(0, cwd + 3, &cwdlen);
  208.       cwdlen = strlen(cwd);
  209.     }
  210.     if (source[0] == '/' || source[0] == '\')
  211.     {
  212.       if (source[1] == '/' || source[1] == '\')
  213.         buffer[0] = 0; /* UNC names */
  214.       else
  215.       {
  216.         strncpy(buffer, cwd, 2);
  217.         buffer[2] = 0;
  218.       }
  219.     }
  220.     else
  221.     {
  222.       strcpy(buffer, cwd);
  223.       if (cwd[cwdlen - 1] != '\' && cwd[cwdlen - 1] != '/')
  224.         strcat(buffer, "/");
  225.     }
  226.   }
  227.   strcat(buffer, source);
  228.   for (ptr = buffer; *ptr; ptr++)
  229.     if (*ptr == '/')
  230.       *ptr = '\';
  231.   if (ptr[-1] == '\')
  232.     ptr[-1] = 0;
  233.   strupr(buffer);
  234. }
  235. static int acl_bin2text(char *data, char *text)
  236. {
  237.   ACCINFO *ai;
  238.   ACCLIST *al;
  239.   U_INT cnt, offs;
  240.   ai = (ACCINFO *) data;
  241.   al = (ACCLIST *) (data + sizeof(ACCINFO));
  242.   offs = sprintf(text, "ACL1:%X,%dn",
  243.                  ai -> acc_attr, ai -> acc_count);
  244.   for (cnt = 0; cnt < ai -> acc_count; cnt++)
  245.     offs += sprintf(text + offs, "%s,%Xn",
  246.                     al[cnt].acl_ugname, al[cnt].acl_access);
  247.   return strlen(text);
  248. }
  249. int acl_get(char *server, const char *resource, char *buffer)
  250. {
  251.   USHORT datalen;
  252.   PSZ srv = NULL;
  253.   int rc;
  254.   if (!acl_init())
  255.     return -1;
  256.   if (server)
  257.     srv = server;
  258.   acl_mkpath(path, resource);
  259.   datalen = 0;
  260.   rc = NetAccessGetInfo(srv, path, 1, data, ACL_BUFFERSIZE, &datalen);
  261.   if (rc == 0)
  262.     acl_bin2text(data, buffer);
  263.   return rc;
  264. }
  265. static int acl_text2bin(char *data, char *text, char *path)
  266. {
  267.   ACCINFO *ai;
  268.   ACCLIST *al;
  269.   char *ptr, *ptr2;
  270.   U_INT cnt;
  271.   ai = (ACCINFO *) data;
  272.   ai -> acc_resource_name = PTR16(path);
  273.   if (sscanf(text, "ACL1:%hX,%hd",
  274.              &ai -> acc_attr, &ai -> acc_count) != 2)
  275.     return ERROR_INVALID_PARAMETER;
  276.   al = (ACCLIST *) (data + sizeof(ACCINFO));
  277.   ptr = strchr(text, 'n') + 1;
  278.   for (cnt = 0; cnt < ai -> acc_count; cnt++)
  279.   {
  280.     ptr2 = strchr(ptr, ',');
  281.     strncpy(al[cnt].acl_ugname, ptr, ptr2 - ptr);
  282.     al[cnt].acl_ugname[ptr2 - ptr] = 0;
  283.     sscanf(ptr2 + 1, "%hx", &al[cnt].acl_access);
  284.     ptr = strchr(ptr, 'n') + 1;
  285.   }
  286.   return sizeof(ACCINFO) + ai -> acc_count * sizeof(ACCLIST);
  287. }
  288. int acl_set(char *server, const char *resource, char *buffer)
  289. {
  290.   USHORT datalen;
  291.   PSZ srv = NULL;
  292.   if (!acl_init())
  293.     return -1;
  294.   if (server)
  295.     srv = server;
  296.   acl_mkpath(path, resource);
  297.   ai -> acc_resource_name = PTR16(path);
  298.   ai -> acc_attr = 0;
  299.   ai -> acc_count = 0;
  300.   NetAccessAdd(srv, 1, ai, sizeof(ACCINFO));
  301.   /* Ignore any errors, most probably because ACL already exists. */
  302.   /* In any such case, try updating the existing ACL. */
  303.   datalen = acl_text2bin(data, buffer, path);
  304.   return NetAccessSetInfo(srv, path, 1, data, datalen, 0);
  305. }
  306. /* end of os2acl.c */