windows-links-20040921
[openafs.git] / src / WINNT / afsd / cm_utils.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 #include <afs/param.h>
11 #include <afs/stds.h>
12
13 #ifndef DJGPP
14 #include <windows.h>
15 #include <winsock2.h>
16 #endif /* !DJGPP */
17 #include <string.h>
18 #include <malloc.h>
19
20 #include <osi.h>
21 #include <rx/rx.h>
22
23 #include "afsd.h"
24
25 static osi_once_t cm_utilsOnce;
26
27 osi_rwlock_t cm_utilsLock;
28
29 cm_space_t *cm_spaceListp;
30
31 long cm_MapRPCError(long error, cm_req_t *reqp)
32 {
33     if (error == 0) 
34         return 0;
35
36     /* If we had to stop retrying, report our saved error code. */
37     if (reqp && error == CM_ERROR_TIMEDOUT) {
38         if (reqp->accessError)
39             return reqp->accessError;
40         if (reqp->volumeError)
41             return reqp->volumeError;
42         if (reqp->rpcError)
43             return reqp->rpcError;
44         return error;
45     }
46
47     if (error < 0) 
48         error = CM_ERROR_TIMEDOUT;
49     else if (error == 30) 
50         error = CM_ERROR_READONLY;
51     else if (error == 13) 
52         error = CM_ERROR_NOACCESS;
53     else if (error == 18) 
54         error = CM_ERROR_CROSSDEVLINK;
55     else if (error == 17) 
56         error = CM_ERROR_EXISTS;
57     else if (error == 20) 
58         error = CM_ERROR_NOTDIR;
59     else if (error == 2) 
60         error = CM_ERROR_NOSUCHFILE;
61     else if (error == 11                /* EAGAIN, most servers */
62              || error == 35)    /* EAGAIN, Digital UNIX */
63         error = CM_ERROR_WOULDBLOCK;
64     else if (error == VDISKFULL
65               || error == 28)        /* ENOSPC */ 
66         error = CM_ERROR_SPACE;
67     else if (error == VOVERQUOTA
68               || error == 49         /* EDQUOT on Solaris */
69               || error == 88            /* EDQUOT on AIX */
70               || error == 69            /* EDQUOT on Digital UNIX and HPUX */
71               || error == 122        /* EDQUOT on Linux */
72               || error == 1133)      /* EDQUOT on Irix  */
73         error = CM_ERROR_QUOTA;
74     else if (error == VNOVNODE) 
75         error = CM_ERROR_BADFD;
76     else if (error == 21)
77         return CM_ERROR_ISDIR;
78     return error;
79 }
80
81 long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp)
82 {
83         if (error == 0) return 0;
84
85         /* If we had to stop retrying, report our saved error code. */
86         if (reqp && error == CM_ERROR_TIMEDOUT) {
87                 if (reqp->accessError)
88                         return reqp->accessError;
89                 if (reqp->volumeError)
90                         return reqp->volumeError;
91                 if (reqp->rpcError)
92                         return reqp->rpcError;
93                 return error;
94         }
95
96         if (error < 0) error = CM_ERROR_TIMEDOUT;
97         else if (error == 30) error = CM_ERROR_READONLY;
98         else if (error == 20) error = CM_ERROR_NOTDIR;
99         else if (error == 13) error = CM_ERROR_NOACCESS;
100         else if (error == 2) error = CM_ERROR_NOSUCHFILE;
101         else if (error == 17            /* AIX */
102                  || error == 66         /* SunOS 4, Digital UNIX */
103                  || error == 93         /* Solaris 2, IRIX */
104                  || error == 247)       /* HP/UX */
105                 error = CM_ERROR_NOTEMPTY;
106         return error;
107 }
108
109 long cm_MapVLRPCError(long error, cm_req_t *reqp)
110 {
111         if (error == 0) return 0;
112
113         /* If we had to stop retrying, report our saved error code. */
114         if (reqp && error == CM_ERROR_TIMEDOUT) {
115                 if (reqp->accessError)
116                         return reqp->accessError;
117                 if (reqp->volumeError)
118                         return reqp->volumeError;
119                 if (reqp->rpcError)
120                         return reqp->rpcError;
121                 return error;
122         }
123
124         if (error < 0) error = CM_ERROR_TIMEDOUT;
125         else if (error == VL_NOENT) error = CM_ERROR_NOSUCHVOLUME;
126         return error;
127 }
128
129 cm_space_t *cm_GetSpace(void)
130 {
131         cm_space_t *tsp;
132
133         if (osi_Once(&cm_utilsOnce)) {
134                 lock_InitializeRWLock(&cm_utilsLock, "cm_utilsLock");
135                 osi_EndOnce(&cm_utilsOnce);
136         }
137         
138         lock_ObtainWrite(&cm_utilsLock);
139         if (tsp = cm_spaceListp) {
140                 cm_spaceListp = tsp->nextp;
141         }
142         else tsp = (cm_space_t *) malloc(sizeof(cm_space_t));
143         (void) memset(tsp, 0, sizeof(cm_space_t));
144         lock_ReleaseWrite(&cm_utilsLock);
145         
146         return tsp;
147 }
148
149 void cm_FreeSpace(cm_space_t *tsp)
150 {
151         lock_ObtainWrite(&cm_utilsLock);
152         tsp->nextp = cm_spaceListp;
153         cm_spaceListp = tsp;
154         lock_ReleaseWrite(&cm_utilsLock);
155 }