2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afs/param.h>
18 #define EWOULDBLOCK WSAEWOULDBLOCK
19 #define EINPROGRESS WSAEINPROGRESS
20 #define EALREADY WSAEALREADY
21 #define ENOTSOCK WSAENOTSOCK
22 #define EDESTADDRREQ WSAEDESTADDRREQ
23 #define EMSGSIZE WSAEMSGSIZE
24 #define EPROTOTYPE WSAEPROTOTYPE
25 #define ENOPROTOOPT WSAENOPROTOOPT
26 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
27 #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
28 #define EOPNOTSUPP WSAEOPNOTSUPP
29 #define EPFNOSUPPORT WSAEPFNOSUPPORT
30 #define EAFNOSUPPORT WSAEAFNOSUPPORT
31 #define EADDRINUSE WSAEADDRINUSE
32 #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
33 #define ENETDOWN WSAENETDOWN
34 #define ENETUNREACH WSAENETUNREACH
35 #define ENETRESET WSAENETRESET
36 #define ECONNABORTED WSAECONNABORTED
37 #define ECONNRESET WSAECONNRESET
38 #define ENOBUFS WSAENOBUFS
39 #define EISCONN WSAEISCONN
40 #define ENOTCONN WSAENOTCONN
41 #define ESHUTDOWN WSAESHUTDOWN
42 #define ETOOMANYREFS WSAETOOMANYREFS
43 #define ETIMEDOUT WSAETIMEDOUT
44 #define ECONNREFUSED WSAECONNREFUSED
48 #define ELOOP WSAELOOP
52 #define ENAMETOOLONG WSAENAMETOOLONG
53 #define EHOSTDOWN WSAEHOSTDOWN
54 #define EHOSTUNREACH WSAEHOSTUNREACH
58 #define ENOTEMPTY WSAENOTEMPTY
59 #define EPROCLIM WSAEPROCLIM
60 #define EUSERS WSAEUSERS
61 #define EDQUOT WSAEDQUOT
62 #define ESTALE WSAESTALE
63 #define EREMOTE WSAEREMOTE
64 #endif /* EWOULDBLOCK */
65 #include <afs/unified_afs.h>
73 #define STRSAFE_NO_DEPRECATE
77 static osi_once_t cm_utilsOnce;
79 osi_rwlock_t cm_utilsLock;
81 cm_space_t *cm_spaceListp;
83 static int et2sys[512];
86 init_et_to_sys_error(void)
88 memset(&et2sys, 0, sizeof(et2sys));
89 et2sys[(UAEPERM - ERROR_TABLE_BASE_uae)] = EPERM;
90 et2sys[(UAENOENT - ERROR_TABLE_BASE_uae)] = ENOENT;
91 et2sys[(UAESRCH - ERROR_TABLE_BASE_uae)] = ESRCH;
92 et2sys[(UAEINTR - ERROR_TABLE_BASE_uae)] = EINTR;
93 et2sys[(UAEIO - ERROR_TABLE_BASE_uae)] = EIO;
94 et2sys[(UAENXIO - ERROR_TABLE_BASE_uae)] = ENXIO;
95 et2sys[(UAE2BIG - ERROR_TABLE_BASE_uae)] = E2BIG;
96 et2sys[(UAENOEXEC - ERROR_TABLE_BASE_uae)] = ENOEXEC;
97 et2sys[(UAEBADF - ERROR_TABLE_BASE_uae)] = EBADF;
98 et2sys[(UAECHILD - ERROR_TABLE_BASE_uae)] = ECHILD;
99 et2sys[(UAEAGAIN - ERROR_TABLE_BASE_uae)] = EAGAIN;
100 et2sys[(UAENOMEM - ERROR_TABLE_BASE_uae)] = ENOMEM;
101 et2sys[(UAEACCES - ERROR_TABLE_BASE_uae)] = EACCES;
102 et2sys[(UAEFAULT - ERROR_TABLE_BASE_uae)] = EFAULT;
103 et2sys[(UAENOTBLK - ERROR_TABLE_BASE_uae)] = ENOTBLK;
104 et2sys[(UAEBUSY - ERROR_TABLE_BASE_uae)] = EBUSY;
105 et2sys[(UAEEXIST - ERROR_TABLE_BASE_uae)] = EEXIST;
106 et2sys[(UAEXDEV - ERROR_TABLE_BASE_uae)] = EXDEV;
107 et2sys[(UAENODEV - ERROR_TABLE_BASE_uae)] = ENODEV;
108 et2sys[(UAENOTDIR - ERROR_TABLE_BASE_uae)] = ENOTDIR;
109 et2sys[(UAEISDIR - ERROR_TABLE_BASE_uae)] = EISDIR;
110 et2sys[(UAEINVAL - ERROR_TABLE_BASE_uae)] = EINVAL;
111 et2sys[(UAENFILE - ERROR_TABLE_BASE_uae)] = ENFILE;
112 et2sys[(UAEMFILE - ERROR_TABLE_BASE_uae)] = EMFILE;
113 et2sys[(UAENOTTY - ERROR_TABLE_BASE_uae)] = ENOTTY;
114 et2sys[(UAETXTBSY - ERROR_TABLE_BASE_uae)] = ETXTBSY;
115 et2sys[(UAEFBIG - ERROR_TABLE_BASE_uae)] = EFBIG;
116 et2sys[(UAENOSPC - ERROR_TABLE_BASE_uae)] = ENOSPC;
117 et2sys[(UAESPIPE - ERROR_TABLE_BASE_uae)] = ESPIPE;
118 et2sys[(UAEROFS - ERROR_TABLE_BASE_uae)] = EROFS;
119 et2sys[(UAEMLINK - ERROR_TABLE_BASE_uae)] = EMLINK;
120 et2sys[(UAEPIPE - ERROR_TABLE_BASE_uae)] = EPIPE;
121 et2sys[(UAEDOM - ERROR_TABLE_BASE_uae)] = EDOM;
122 et2sys[(UAERANGE - ERROR_TABLE_BASE_uae)] = ERANGE;
123 et2sys[(UAEDEADLK - ERROR_TABLE_BASE_uae)] = EDEADLK;
124 et2sys[(UAENAMETOOLONG - ERROR_TABLE_BASE_uae)] = ENAMETOOLONG;
125 et2sys[(UAENOLCK - ERROR_TABLE_BASE_uae)] = ENOLCK;
126 et2sys[(UAENOSYS - ERROR_TABLE_BASE_uae)] = ENOSYS;
127 et2sys[(UAENOTEMPTY - ERROR_TABLE_BASE_uae)] = ENOTEMPTY;
128 et2sys[(UAELOOP - ERROR_TABLE_BASE_uae)] = ELOOP;
129 et2sys[(UAEWOULDBLOCK - ERROR_TABLE_BASE_uae)] = EWOULDBLOCK;
130 et2sys[(UAENOMSG - ERROR_TABLE_BASE_uae)] = ENOMSG;
131 et2sys[(UAEIDRM - ERROR_TABLE_BASE_uae)] = EIDRM;
132 et2sys[(UAECHRNG - ERROR_TABLE_BASE_uae)] = ECHRNG;
133 et2sys[(UAEL2NSYNC - ERROR_TABLE_BASE_uae)] = EL2NSYNC;
134 et2sys[(UAEL3HLT - ERROR_TABLE_BASE_uae)] = EL3HLT;
135 et2sys[(UAEL3RST - ERROR_TABLE_BASE_uae)] = EL3RST;
136 et2sys[(UAELNRNG - ERROR_TABLE_BASE_uae)] = ELNRNG;
137 et2sys[(UAEUNATCH - ERROR_TABLE_BASE_uae)] = EUNATCH;
138 et2sys[(UAENOCSI - ERROR_TABLE_BASE_uae)] = ENOCSI;
139 et2sys[(UAEL2HLT - ERROR_TABLE_BASE_uae)] = EL2HLT;
140 et2sys[(UAEBADE - ERROR_TABLE_BASE_uae)] = EBADE;
141 et2sys[(UAEBADR - ERROR_TABLE_BASE_uae)] = EBADR;
142 et2sys[(UAEXFULL - ERROR_TABLE_BASE_uae)] = EXFULL;
143 et2sys[(UAENOANO - ERROR_TABLE_BASE_uae)] = ENOANO;
144 et2sys[(UAEBADRQC - ERROR_TABLE_BASE_uae)] = EBADRQC;
145 et2sys[(UAEBADSLT - ERROR_TABLE_BASE_uae)] = EBADSLT;
146 et2sys[(UAEBFONT - ERROR_TABLE_BASE_uae)] = EBFONT;
147 et2sys[(UAENOSTR - ERROR_TABLE_BASE_uae)] = ENOSTR;
148 et2sys[(UAENODATA - ERROR_TABLE_BASE_uae)] = ENODATA;
149 et2sys[(UAETIME - ERROR_TABLE_BASE_uae)] = ETIME;
150 et2sys[(UAENOSR - ERROR_TABLE_BASE_uae)] = ENOSR;
151 et2sys[(UAENONET - ERROR_TABLE_BASE_uae)] = ENONET;
152 et2sys[(UAENOPKG - ERROR_TABLE_BASE_uae)] = ENOPKG;
153 et2sys[(UAEREMOTE - ERROR_TABLE_BASE_uae)] = EREMOTE;
154 et2sys[(UAENOLINK - ERROR_TABLE_BASE_uae)] = ENOLINK;
155 et2sys[(UAEADV - ERROR_TABLE_BASE_uae)] = EADV;
156 et2sys[(UAESRMNT - ERROR_TABLE_BASE_uae)] = ESRMNT;
157 et2sys[(UAECOMM - ERROR_TABLE_BASE_uae)] = ECOMM;
158 et2sys[(UAEPROTO - ERROR_TABLE_BASE_uae)] = EPROTO;
159 et2sys[(UAEMULTIHOP - ERROR_TABLE_BASE_uae)] = EMULTIHOP;
160 et2sys[(UAEDOTDOT - ERROR_TABLE_BASE_uae)] = EDOTDOT;
161 et2sys[(UAEBADMSG - ERROR_TABLE_BASE_uae)] = EBADMSG;
162 et2sys[(UAEOVERFLOW - ERROR_TABLE_BASE_uae)] = EOVERFLOW;
163 et2sys[(UAENOTUNIQ - ERROR_TABLE_BASE_uae)] = ENOTUNIQ;
164 et2sys[(UAEBADFD - ERROR_TABLE_BASE_uae)] = EBADFD;
165 et2sys[(UAEREMCHG - ERROR_TABLE_BASE_uae)] = EREMCHG;
166 et2sys[(UAELIBACC - ERROR_TABLE_BASE_uae)] = ELIBACC;
167 et2sys[(UAELIBBAD - ERROR_TABLE_BASE_uae)] = ELIBBAD;
168 et2sys[(UAELIBSCN - ERROR_TABLE_BASE_uae)] = ELIBSCN;
169 et2sys[(UAELIBMAX - ERROR_TABLE_BASE_uae)] = ELIBMAX;
170 et2sys[(UAELIBEXEC - ERROR_TABLE_BASE_uae)] = ELIBEXEC;
171 et2sys[(UAEILSEQ - ERROR_TABLE_BASE_uae)] = EILSEQ;
172 et2sys[(UAERESTART - ERROR_TABLE_BASE_uae)] = ERESTART;
173 et2sys[(UAESTRPIPE - ERROR_TABLE_BASE_uae)] = ESTRPIPE;
174 et2sys[(UAEUSERS - ERROR_TABLE_BASE_uae)] = EUSERS;
175 et2sys[(UAENOTSOCK - ERROR_TABLE_BASE_uae)] = ENOTSOCK;
176 et2sys[(UAEDESTADDRREQ - ERROR_TABLE_BASE_uae)] = EDESTADDRREQ;
177 et2sys[(UAEMSGSIZE - ERROR_TABLE_BASE_uae)] = EMSGSIZE;
178 et2sys[(UAEPROTOTYPE - ERROR_TABLE_BASE_uae)] = EPROTOTYPE;
179 et2sys[(UAENOPROTOOPT - ERROR_TABLE_BASE_uae)] = ENOPROTOOPT;
180 et2sys[(UAEPROTONOSUPPORT - ERROR_TABLE_BASE_uae)] = EPROTONOSUPPORT;
181 et2sys[(UAESOCKTNOSUPPORT - ERROR_TABLE_BASE_uae)] = ESOCKTNOSUPPORT;
182 et2sys[(UAEOPNOTSUPP - ERROR_TABLE_BASE_uae)] = EOPNOTSUPP;
183 et2sys[(UAEPFNOSUPPORT - ERROR_TABLE_BASE_uae)] = EPFNOSUPPORT;
184 et2sys[(UAEAFNOSUPPORT - ERROR_TABLE_BASE_uae)] = EAFNOSUPPORT;
185 et2sys[(UAEADDRINUSE - ERROR_TABLE_BASE_uae)] = EADDRINUSE;
186 et2sys[(UAEADDRNOTAVAIL - ERROR_TABLE_BASE_uae)] = EADDRNOTAVAIL;
187 et2sys[(UAENETDOWN - ERROR_TABLE_BASE_uae)] = ENETDOWN;
188 et2sys[(UAENETUNREACH - ERROR_TABLE_BASE_uae)] = ENETUNREACH;
189 et2sys[(UAENETRESET - ERROR_TABLE_BASE_uae)] = ENETRESET;
190 et2sys[(UAECONNABORTED - ERROR_TABLE_BASE_uae)] = ECONNABORTED;
191 et2sys[(UAECONNRESET - ERROR_TABLE_BASE_uae)] = ECONNRESET;
192 et2sys[(UAENOBUFS - ERROR_TABLE_BASE_uae)] = ENOBUFS;
193 et2sys[(UAEISCONN - ERROR_TABLE_BASE_uae)] = EISCONN;
194 et2sys[(UAENOTCONN - ERROR_TABLE_BASE_uae)] = ENOTCONN;
195 et2sys[(UAESHUTDOWN - ERROR_TABLE_BASE_uae)] = ESHUTDOWN;
196 et2sys[(UAETOOMANYREFS - ERROR_TABLE_BASE_uae)] = ETOOMANYREFS;
197 et2sys[(UAETIMEDOUT - ERROR_TABLE_BASE_uae)] = ETIMEDOUT;
198 et2sys[(UAECONNREFUSED - ERROR_TABLE_BASE_uae)] = ECONNREFUSED;
199 et2sys[(UAEHOSTDOWN - ERROR_TABLE_BASE_uae)] = EHOSTDOWN;
200 et2sys[(UAEHOSTUNREACH - ERROR_TABLE_BASE_uae)] = EHOSTUNREACH;
201 et2sys[(UAEALREADY - ERROR_TABLE_BASE_uae)] = EALREADY;
202 et2sys[(UAEINPROGRESS - ERROR_TABLE_BASE_uae)] = EINPROGRESS;
203 et2sys[(UAESTALE - ERROR_TABLE_BASE_uae)] = ESTALE;
204 et2sys[(UAEUCLEAN - ERROR_TABLE_BASE_uae)] = EUCLEAN;
205 et2sys[(UAENOTNAM - ERROR_TABLE_BASE_uae)] = ENOTNAM;
206 et2sys[(UAENAVAIL - ERROR_TABLE_BASE_uae)] = ENAVAIL;
207 et2sys[(UAEISNAM - ERROR_TABLE_BASE_uae)] = EISNAM;
208 et2sys[(UAEREMOTEIO - ERROR_TABLE_BASE_uae)] = EREMOTEIO;
209 et2sys[(UAEDQUOT - ERROR_TABLE_BASE_uae)] = EDQUOT;
210 et2sys[(UAENOMEDIUM - ERROR_TABLE_BASE_uae)] = ENOMEDIUM;
211 et2sys[(UAEMEDIUMTYPE - ERROR_TABLE_BASE_uae)] = EMEDIUMTYPE;
215 et_to_sys_error(afs_int32 in)
217 if (in < ERROR_TABLE_BASE_uae || in >= ERROR_TABLE_BASE_uae + 512)
219 if (et2sys[in - ERROR_TABLE_BASE_uae] != 0)
220 return et2sys[in - ERROR_TABLE_BASE_uae];
224 long cm_MapRPCError(long error, cm_req_t *reqp)
229 /* If we had to stop retrying, report our saved error code. */
230 if (reqp && error == CM_ERROR_TIMEDOUT) {
231 if (reqp->accessError)
232 return reqp->accessError;
233 if (reqp->volumeError)
234 return reqp->volumeError;
236 return reqp->rpcError;
240 error = et_to_sys_error(error);
243 error = CM_ERROR_TIMEDOUT;
244 else if (error == EROFS)
245 error = CM_ERROR_READONLY;
246 else if (error == EACCES)
247 error = CM_ERROR_NOACCESS;
248 else if (error == EXDEV)
249 error = CM_ERROR_CROSSDEVLINK;
250 else if (error == EEXIST)
251 error = CM_ERROR_EXISTS;
252 else if (error == ENOTDIR)
253 error = CM_ERROR_NOTDIR;
254 else if (error == ENOENT)
255 error = CM_ERROR_NOSUCHFILE;
256 else if (error == EAGAIN
257 || error == 35 /* EAGAIN, Digital UNIX */
258 || error == WSAEWOULDBLOCK)
259 error = CM_ERROR_WOULDBLOCK;
260 else if (error == VDISKFULL
262 error = CM_ERROR_SPACE;
263 else if (error == VOVERQUOTA
265 || error == 49 /* EDQUOT on Solaris */
266 || error == 88 /* EDQUOT on AIX */
267 || error == 69 /* EDQUOT on Digital UNIX and HPUX */
268 || error == 122 /* EDQUOT on Linux */
269 || error == 1133) /* EDQUOT on Irix */
270 error = CM_ERROR_QUOTA;
271 else if (error == VNOVNODE)
272 error = CM_ERROR_BADFD;
273 else if (error == EISDIR)
274 return CM_ERROR_ISDIR;
278 long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp)
283 /* If we had to stop retrying, report our saved error code. */
284 if (reqp && error == CM_ERROR_TIMEDOUT) {
285 if (reqp->accessError)
286 return reqp->accessError;
287 if (reqp->volumeError)
288 return reqp->volumeError;
290 return reqp->rpcError;
294 error = et_to_sys_error(error);
297 error = CM_ERROR_TIMEDOUT;
298 else if (error == EROFS)
299 error = CM_ERROR_READONLY;
300 else if (error == ENOTDIR)
301 error = CM_ERROR_NOTDIR;
302 else if (error == EACCES)
303 error = CM_ERROR_NOACCESS;
304 else if (error == ENOENT)
305 error = CM_ERROR_NOSUCHFILE;
306 else if (error == ENOTEMPTY
307 || error == 17 /* AIX */
308 || error == 66 /* SunOS 4, Digital UNIX */
309 || error == 93 /* Solaris 2, IRIX */
310 || error == 247) /* HP/UX */
311 error = CM_ERROR_NOTEMPTY;
315 long cm_MapVLRPCError(long error, cm_req_t *reqp)
317 if (error == 0) return 0;
319 /* If we had to stop retrying, report our saved error code. */
320 if (reqp && error == CM_ERROR_TIMEDOUT) {
321 if (reqp->accessError)
322 return reqp->accessError;
323 if (reqp->volumeError)
324 return reqp->volumeError;
326 return reqp->rpcError;
330 error = et_to_sys_error(error);
333 error = CM_ERROR_TIMEDOUT;
334 else if (error == VL_NOENT || error == VL_BADNAME)
335 error = CM_ERROR_NOSUCHVOLUME;
339 cm_space_t *cm_GetSpace(void)
343 if (osi_Once(&cm_utilsOnce)) {
344 lock_InitializeRWLock(&cm_utilsLock, "cm_utilsLock", LOCK_HIERARCHY_UTILS_GLOBAL);
345 osi_EndOnce(&cm_utilsOnce);
348 lock_ObtainWrite(&cm_utilsLock);
349 if (tsp = cm_spaceListp) {
350 cm_spaceListp = tsp->nextp;
352 else tsp = (cm_space_t *) malloc(sizeof(cm_space_t));
353 (void) memset(tsp, 0, sizeof(cm_space_t));
354 lock_ReleaseWrite(&cm_utilsLock);
359 void cm_FreeSpace(cm_space_t *tsp)
361 lock_ObtainWrite(&cm_utilsLock);
362 tsp->nextp = cm_spaceListp;
364 lock_ReleaseWrite(&cm_utilsLock);
367 /* characters that are legal in an 8.3 name */
369 * We used to have 1's for all characters from 128 to 254. But
370 * the NT client behaves better if we create an 8.3 name for any
371 * name that has a character with the high bit on, and if we
372 * delete those characters from 8.3 names. In particular, see
373 * Sybase defect 10859.
375 char cm_LegalChars[256] = {
376 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
377 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
378 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0,
379 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
380 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
381 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
382 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
383 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
384 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
385 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
389 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
390 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
391 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
394 #define ISLEGALCHAR(c) ((c) < 256 && (c) > 0 && cm_LegalChars[(c)] != 0)
396 /* return true iff component is a valid 8.3 name */
397 int cm_Is8Dot3(clientchar_t *namep)
403 if (namep == NULL || !namep[0])
407 * can't have a leading dot;
408 * special case for . and ..
410 if (namep[0] == '.') {
413 if (namep[1] == '.' && namep[2] == 0)
417 while (tc = *namep++) {
419 /* saw another dot */
420 if (sawDot) return 0; /* second dot */
425 if (!ISLEGALCHAR(tc))
428 if (!sawDot && charCount > 8)
429 /* more than 8 chars in name */
431 if (sawDot && charCount > 3)
432 /* more than 3 chars in extension */
439 * Number unparsing map for generating 8.3 names;
440 * The version taken from DFS was on drugs.
441 * You can't include '&' and '@' in a file name.
443 char cm_8Dot3Mapping[42] =
444 {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
445 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
446 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
447 'V', 'W', 'X', 'Y', 'Z', '_', '-', '$', '#', '!', '{', '}'
449 int cm_8Dot3MapSize = sizeof(cm_8Dot3Mapping);
451 void cm_Gen8Dot3NameInt(const fschar_t * longname, cm_dirFid_t * pfid,
452 clientchar_t *shortName, clientchar_t **shortNameEndp)
456 int vnode = ntohl(pfid->vnode);
458 int validExtension = 0;
462 /* Unparse the file's vnode number to get a "uniquifier" */
464 number[nsize] = cm_8Dot3Mapping[vnode % cm_8Dot3MapSize];
466 vnode /= cm_8Dot3MapSize;
470 * Look for valid extension. There has to be a dot, and
471 * at least one of the characters following has to be legal.
473 lastDot = strrchr(longname, '.');
475 temp = lastDot; temp++;
483 /* Copy name characters */
484 for (i = 0, name = longname;
485 i < (7 - nsize) && name != lastDot; ) {
490 if (!ISLEGALCHAR(tc))
493 *shortName++ = toupper(tc);
499 /* Copy uniquifier characters */
500 for (i=0; i < nsize; i++) {
501 *shortName++ = number[i];
504 if (validExtension) {
505 /* Copy extension characters */
506 *shortName++ = *lastDot++; /* copy dot */
507 for (i = 0, tc = *lastDot++;
510 if (ISLEGALCHAR(tc)) {
512 *shortName++ = toupper(tc);
521 *shortNameEndp = shortName;
524 void cm_Gen8Dot3NameIntW(const clientchar_t * longname, cm_dirFid_t * pfid,
525 clientchar_t *shortName, clientchar_t **shortNameEndp)
527 clientchar_t number[12];
529 int vnode = ntohl(pfid->vnode);
530 clientchar_t *lastDot;
531 int validExtension = 0;
532 clientchar_t tc, *temp;
533 const clientchar_t *name;
535 /* Unparse the file's vnode number to get a "uniquifier" */
537 number[nsize] = cm_8Dot3Mapping[vnode % cm_8Dot3MapSize];
539 vnode /= cm_8Dot3MapSize;
543 * Look for valid extension. There has to be a dot, and
544 * at least one of the characters following has to be legal.
546 lastDot = cm_ClientStrRChr(longname, '.');
548 temp = lastDot; temp++;
556 /* Copy name characters */
557 for (i = 0, name = longname;
558 i < (7 - nsize) && name != lastDot; ) {
563 if (!ISLEGALCHAR(tc))
566 *shortName++ = toupper((char) tc);
572 /* Copy uniquifier characters */
573 for (i=0; i < nsize; i++) {
574 *shortName++ = number[i];
577 if (validExtension) {
578 /* Copy extension characters */
579 *shortName++ = *lastDot++; /* copy dot */
580 for (i = 0, tc = *lastDot++;
583 if (ISLEGALCHAR(tc)) {
585 *shortName++ = toupper(tc);
594 *shortNameEndp = shortName;
597 /*! \brief Compare 'pattern' (containing metacharacters '*' and '?') with the file name 'name'.
599 \note This procedure works recursively calling itself.
601 \param[in] pattern string containing metacharacters.
602 \param[in] name File name to be compared with 'pattern'.
604 \return BOOL : TRUE/FALSE (match/mistmatch)
607 szWildCardMatchFileName(clientchar_t * pattern, clientchar_t * name, int casefold)
609 clientchar_t upattern[MAX_PATH];
610 clientchar_t uname[MAX_PATH];
612 clientchar_t * pename; // points to the last 'name' character
614 clientchar_t * pattern_next;
617 cm_ClientStrCpy(upattern, lengthof(upattern), pattern);
618 cm_ClientStrUpr(upattern);
621 cm_ClientStrCpy(uname, lengthof(uname), name);
622 cm_ClientStrUpr(uname);
625 /* The following translations all work on single byte
627 for (p=upattern; *p; p++) {
628 if (*p == '"') *p = '.'; continue;
629 if (*p == '<') *p = '*'; continue;
630 if (*p == '>') *p = '?'; continue;
633 for (p=uname; *p; p++) {
634 if (*p == '"') *p = '.'; continue;
635 if (*p == '<') *p = '*'; continue;
636 if (*p == '>') *p = '?'; continue;
640 pename = cm_ClientCharThis(name + cm_ClientStrLen(name));
645 pattern = cm_ClientCharNext(pattern);
648 name = cm_ClientCharNext(name);
652 pattern = cm_ClientCharNext(pattern);
653 if (*pattern == '\0')
656 pattern_next = cm_ClientCharNext(pattern);
658 for (p = pename; p >= name; p = cm_ClientCharPrev(p)) {
659 if (*p == *pattern &&
660 szWildCardMatchFileName(pattern_next,
661 cm_ClientCharNext(p), FALSE))
664 if (*pattern == '.' && *pattern_next == '\0') {
665 for (p = name; p && *p; p = cm_ClientCharNext(p))
675 if (*name != *pattern)
677 pattern = cm_ClientCharNext(pattern);
678 name = cm_ClientCharNext(name);
683 /* if all we have left are wildcards, then we match */
684 for (;*pattern; pattern = cm_ClientCharNext(pattern)) {
685 if (*pattern != '*' && *pattern != '?')
691 /* do a case-folding search of the star name mask with the name in namep.
692 * Return 1 if we match, otherwise 0.
694 int cm_MatchMask(clientchar_t *namep, clientchar_t *maskp, int flags)
696 clientchar_t *newmask, lastchar = _C('\0');
697 int i, j, casefold, retval;
698 int star = 0, qmark = 0, dot = 0;
700 /* make sure we only match 8.3 names, if requested */
701 if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep))
704 casefold = (flags & CM_FLAG_CASEFOLD) ? 1 : 0;
706 /* optimize the pattern:
707 * if there is a mixture of '?' and '*',
708 * for example the sequence "*?*?*?*"
709 * must be turned into the form "*"
711 newmask = (clientchar_t *)malloc((cm_ClientStrLen(maskp)+2)*sizeof(clientchar_t));
712 for ( i=0, j=0, star=0, qmark=0; maskp[i]; i++) {
714 switch ( maskp[i] ) {
729 } else if ( qmark ) {
733 newmask[j++] = maskp[i];
740 } else if ( qmark ) {
744 if (dot == 0 && lastchar == '<')
748 retval = szWildCardMatchFileName(newmask, namep, casefold) ? 1:0;
755 cm_TargetPerceivedAsDirectory(const fschar_t *target)
759 ext = PathFindExtension(target);
767 cm_LoadAfsdHookLib(void)
773 if (!GetModuleFileName(NULL, dllname, sizeof(dllname)))
776 p = strrchr(dllname, '\\');
779 strcpy(p, AFSD_HOOK_DLL);
780 hLib = LoadLibrary(dllname);
782 hLib = LoadLibrary(AFSD_HOOK_DLL);