]> git.saurik.com Git - wxWidgets.git/blob - utils/Install/sfxzip/os2acl.c
test for bug with new wu-ftpd
[wxWidgets.git] / utils / Install / sfxzip / os2acl.c
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 /*
10 * supported 32-bit compilers:
11 * - emx+gcc
12 * - IBM C Set++ 2.1 or newer
13 * - Watcom C/C++ 10.0 or newer
14 *
15 * supported 16-bit compilers:
16 * - MS C 6.00A
17 * - Watcom C/C++ 10.0 or newer
18 *
19 * supported OS/2 LAN environments:
20 * - IBM LAN Server/Requester 3.0, 4.0 and 5.0 (Warp Server)
21 * - IBM Peer 1.0 (Warp Connect)
22 */
23
24 #ifdef KUR
25 static char *rcsid =
26 "$Id$";
27 static char *rcsrev = "$Revision$";
28 #endif
29
30 /*
31 * $Log$
32 * Revision 1.2 2000/07/15 19:50:50 cvsuser
33 * merged 2.2 branch
34 *
35 * Revision 1.1.2.1 2000/04/11 12:38:06 BS
36 * Added wxInstall a self extracting installation program using wxWindows.
37 *
38 * Revision 1.3 1996/04/03 19:18:27 rommel
39 * minor fixes
40 *
41 * Revision 1.2 1996/03/30 22:03:52 rommel
42 * avoid frequent dynamic allocation for every call
43 * streamlined code
44 *
45 * Revision 1.1 1996/03/30 09:35:00 rommel
46 * Initial revision
47 *
48 */
49
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <ctype.h>
54 #include <malloc.h>
55
56 #define INCL_NOPM
57 #define INCL_DOS
58 #define INCL_DOSERRORS
59 #include <os2.h>
60
61 #include "os2/os2acl.h"
62
63 #define UNLEN 20
64
65 #if defined(__WATCOMC__) && defined(__386__) && !defined(__32BIT__)
66 #define __32BIT__
67 #endif
68
69 #ifdef __32BIT__
70 typedef ULONG U_INT;
71 #ifdef __EMX__
72 #define PSTR16 _far16ptr
73 #define PTR16(x) _emx_32to16(x)
74 #else /* other 32-bit */
75 #define PSTR16 PCHAR16
76 #define PTR16(x) ((PCHAR16)(x))
77 #endif
78 #else /* 16-bit */
79 typedef USHORT U_INT;
80 #define PSTR16 PSZ
81 #define PTR16(x) (x)
82 #endif
83
84 typedef struct access_list
85 {
86 char acl_ugname[UNLEN+1];
87 char acl_pad;
88 USHORT acl_access;
89 }
90 ACCLIST;
91
92 typedef struct access_info
93 {
94 PSTR16 acc_resource_name;
95 USHORT acc_attr;
96 USHORT acc_count;
97 }
98 ACCINFO;
99
100 static ACCINFO *ai;
101 static char *path, *data;
102
103 #ifdef __32BIT__
104
105 #ifdef __EMX__
106
107 static USHORT (APIENTRY *_NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
108 USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
109 static USHORT (APIENTRY *_NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
110 USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
111 static USHORT (APIENTRY *_NetAccessAdd)(PSZ pszServer,
112 USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
113
114 USHORT NetAccessGetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
115 PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail)
116 {
117 return (USHORT)
118 (_THUNK_PROLOG (4+4+2+4+2+4);
119 _THUNK_FLAT (pszServer);
120 _THUNK_FLAT (pszResource);
121 _THUNK_SHORT (sLevel);
122 _THUNK_FLAT (pbBuffer);
123 _THUNK_SHORT (cbBuffer);
124 _THUNK_FLAT (pcbTotalAvail);
125 _THUNK_CALLI (_emx_32to16(_NetAccessGetInfo)));
126 }
127
128 USHORT NetAccessSetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
129 PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum)
130 {
131 return (USHORT)
132 (_THUNK_PROLOG (4+4+2+4+2+2);
133 _THUNK_FLAT (pszServer);
134 _THUNK_FLAT (pszResource);
135 _THUNK_SHORT (sLevel);
136 _THUNK_FLAT (pbBuffer);
137 _THUNK_SHORT (cbBuffer);
138 _THUNK_SHORT (sParmNum);
139 _THUNK_CALLI (_emx_32to16(_NetAccessSetInfo)));
140 }
141
142 USHORT NetAccessAdd(PSZ pszServer, USHORT sLevel,
143 PVOID pbBuffer, USHORT cbBuffer)
144 {
145 return (USHORT)
146 (_THUNK_PROLOG (4+2+4+2);
147 _THUNK_FLAT (pszServer);
148 _THUNK_SHORT (sLevel);
149 _THUNK_FLAT (pbBuffer);
150 _THUNK_SHORT (cbBuffer);
151 _THUNK_CALLI (_emx_32to16(_NetAccessAdd)));
152 }
153
154 #else /* other 32-bit */
155
156 APIRET16 (* APIENTRY16 NetAccessGetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
157 USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, PVOID16 pcbTotalAvail);
158 APIRET16 (* APIENTRY16 NetAccessSetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
159 USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, USHORT sParmNum);
160 APIRET16 (* APIENTRY16 NetAccessAdd)(PCHAR16 pszServer,
161 USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer);
162
163 #define _NetAccessGetInfo NetAccessGetInfo
164 #define _NetAccessSetInfo NetAccessSetInfo
165 #define _NetAccessAdd NetAccessAdd
166
167 #if !defined(__IBMC__) || !defined(__TILED__)
168 #define _tmalloc malloc
169 #define _tfree free
170 #endif
171
172 #endif
173 #else /* 16-bit */
174
175 USHORT (APIENTRY *NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
176 USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
177 USHORT (APIENTRY *NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
178 USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
179 USHORT (APIENTRY *NetAccessAdd)(PSZ pszServer,
180 USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
181
182 #define _NetAccessGetInfo NetAccessGetInfo
183 #define _NetAccessSetInfo NetAccessSetInfo
184 #define _NetAccessAdd NetAccessAdd
185
186 #define _tmalloc malloc
187 #define _tfree free
188
189 #define DosQueryProcAddr(handle, ord, name, funcptr) \
190 DosGetProcAddr(handle, name, funcptr)
191 #define DosQueryCurrentDir DosQCurDir
192 #define DosQueryCurrentDisk DosQCurDisk
193
194 #endif
195
196
197 static BOOL acl_init(void)
198 {
199 static BOOL initialized, netapi_avail;
200 HMODULE netapi;
201 char buf[256];
202
203 if (initialized)
204 return netapi_avail;
205
206 initialized = TRUE;
207
208 if (DosLoadModule(buf, sizeof(buf), "NETAPI", &netapi))
209 return FALSE;
210
211 if (DosQueryProcAddr(netapi, 0, "NETACCESSGETINFO", (PFN *) &_NetAccessGetInfo) ||
212 DosQueryProcAddr(netapi, 0, "NETACCESSSETINFO", (PFN *) &_NetAccessSetInfo) ||
213 DosQueryProcAddr(netapi, 0, "NETACCESSADD", (PFN *) &_NetAccessAdd))
214 return FALSE;
215
216 #if defined(__WATCOMC__) && defined(__386__)
217 NetAccessGetInfo = (PVOID) (ULONG) (PVOID16) NetAccessGetInfo;
218 NetAccessSetInfo = (PVOID) (ULONG) (PVOID16) NetAccessSetInfo;
219 NetAccessAdd = (PVOID) (ULONG) (PVOID16) NetAccessAdd;
220 #endif
221
222 if ((path = _tmalloc(CCHMAXPATH)) == NULL)
223 return FALSE;
224 if ((data = _tmalloc(ACL_BUFFERSIZE)) == NULL)
225 return FALSE;
226 if ((ai = _tmalloc(sizeof(ACCINFO))) == NULL)
227 return -1;
228
229 netapi_avail = TRUE;
230
231 return netapi_avail;
232 }
233
234 static void acl_mkpath(char *buffer, const char *source)
235 {
236 char *ptr;
237 static char cwd[CCHMAXPATH];
238 static U_INT cwdlen;
239 U_INT cdrive;
240 ULONG drivemap;
241
242 if (isalpha(source[0]) && source[1] == ':')
243 buffer[0] = 0; /* fully qualified names */
244 else
245 {
246 if (cwd[0] == 0)
247 {
248 DosQueryCurrentDisk(&cdrive, &drivemap);
249 cwd[0] = (char)(cdrive + '@');
250 cwd[1] = ':';
251 cwd[2] = '\\';
252 cwdlen = sizeof(cwd) - 3;
253 DosQueryCurrentDir(0, cwd + 3, &cwdlen);
254 cwdlen = strlen(cwd);
255 }
256
257 if (source[0] == '/' || source[0] == '\\')
258 {
259 if (source[1] == '/' || source[1] == '\\')
260 buffer[0] = 0; /* UNC names */
261 else
262 {
263 strncpy(buffer, cwd, 2);
264 buffer[2] = 0;
265 }
266 }
267 else
268 {
269 strcpy(buffer, cwd);
270 if (cwd[cwdlen - 1] != '\\' && cwd[cwdlen - 1] != '/')
271 strcat(buffer, "/");
272 }
273 }
274
275 strcat(buffer, source);
276
277 for (ptr = buffer; *ptr; ptr++)
278 if (*ptr == '/')
279 *ptr = '\\';
280
281 if (ptr[-1] == '\\')
282 ptr[-1] = 0;
283
284 strupr(buffer);
285 }
286
287 static int acl_bin2text(char *data, char *text)
288 {
289 ACCINFO *ai;
290 ACCLIST *al;
291 U_INT cnt, offs;
292
293 ai = (ACCINFO *) data;
294 al = (ACCLIST *) (data + sizeof(ACCINFO));
295
296 offs = sprintf(text, "ACL1:%X,%d\n",
297 ai -> acc_attr, ai -> acc_count);
298
299 for (cnt = 0; cnt < ai -> acc_count; cnt++)
300 offs += sprintf(text + offs, "%s,%X\n",
301 al[cnt].acl_ugname, al[cnt].acl_access);
302
303 return strlen(text);
304 }
305
306 int acl_get(char *server, const char *resource, char *buffer)
307 {
308 USHORT datalen;
309 PSZ srv = NULL;
310 int rc;
311
312 if (!acl_init())
313 return -1;
314
315 if (server)
316 srv = server;
317
318 acl_mkpath(path, resource);
319 datalen = 0;
320
321 rc = NetAccessGetInfo(srv, path, 1, data, ACL_BUFFERSIZE, &datalen);
322
323 if (rc == 0)
324 acl_bin2text(data, buffer);
325
326 return rc;
327 }
328
329 static int acl_text2bin(char *data, char *text, char *path)
330 {
331 ACCINFO *ai;
332 ACCLIST *al;
333 char *ptr, *ptr2;
334 U_INT cnt;
335
336 ai = (ACCINFO *) data;
337 ai -> acc_resource_name = PTR16(path);
338
339 if (sscanf(text, "ACL1:%hX,%hd",
340 &ai -> acc_attr, &ai -> acc_count) != 2)
341 return ERROR_INVALID_PARAMETER;
342
343 al = (ACCLIST *) (data + sizeof(ACCINFO));
344 ptr = strchr(text, '\n') + 1;
345
346 for (cnt = 0; cnt < ai -> acc_count; cnt++)
347 {
348 ptr2 = strchr(ptr, ',');
349 strncpy(al[cnt].acl_ugname, ptr, ptr2 - ptr);
350 al[cnt].acl_ugname[ptr2 - ptr] = 0;
351 sscanf(ptr2 + 1, "%hx", &al[cnt].acl_access);
352 ptr = strchr(ptr, '\n') + 1;
353 }
354
355 return sizeof(ACCINFO) + ai -> acc_count * sizeof(ACCLIST);
356 }
357
358 int acl_set(char *server, const char *resource, char *buffer)
359 {
360 USHORT datalen;
361 PSZ srv = NULL;
362
363 if (!acl_init())
364 return -1;
365
366 if (server)
367 srv = server;
368
369 acl_mkpath(path, resource);
370
371 ai -> acc_resource_name = PTR16(path);
372 ai -> acc_attr = 0;
373 ai -> acc_count = 0;
374
375 NetAccessAdd(srv, 1, ai, sizeof(ACCINFO));
376 /* Ignore any errors, most probably because ACL already exists. */
377 /* In any such case, try updating the existing ACL. */
378
379 datalen = acl_text2bin(data, buffer, path);
380
381 return NetAccessSetInfo(srv, path, 1, data, datalen, 0);
382 }
383
384 /* end of os2acl.c */