security-class-object-leak-20040301
[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) return 0;
34
35         /* If we had to stop retrying, report our saved error code. */
36         if (reqp && error == CM_ERROR_TIMEDOUT) {
37                 if (reqp->accessError)
38                         return reqp->accessError;
39                 if (reqp->volumeError)
40                         return reqp->volumeError;
41                 if (reqp->rpcError)
42                         return reqp->rpcError;
43                 return error;
44         }
45
46         if (error < 0) error = CM_ERROR_TIMEDOUT;
47         else if (error == 30) error = CM_ERROR_READONLY;
48         else if (error == 13) error = CM_ERROR_NOACCESS;
49         else if (error == 18) error = CM_ERROR_CROSSDEVLINK;
50         else if (error == 17) error = CM_ERROR_EXISTS;
51         else if (error == 20) error = CM_ERROR_NOTDIR;
52         else if (error == 2) error = CM_ERROR_NOSUCHFILE;
53         else if (error == 11            /* EAGAIN, most servers */
54                  || error == 35)        /* EAGAIN, Digital UNIX */
55                         error = CM_ERROR_WOULDBLOCK;
56         else if (error == VDISKFULL
57                  || error == 28)        /* ENOSPC */ 
58                         error = CM_ERROR_SPACE;
59         else if (error == VOVERQUOTA
60                  || error == 49         /* EDQUOT on Solaris */
61                  || error == 88         /* EDQUOT on AIX */
62                  || error == 69         /* EDQUOT on Digital UNIX and HPUX */
63                  || error == 122        /* EDQUOT on Linux */
64                  || error == 1133)      /* EDQUOT on Irix  */
65                         error = CM_ERROR_QUOTA;
66         else if (error == VNOVNODE) error = CM_ERROR_BADFD;
67         return error;
68 }
69
70 long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp)
71 {
72         if (error == 0) return 0;
73
74         /* If we had to stop retrying, report our saved error code. */
75         if (reqp && error == CM_ERROR_TIMEDOUT) {
76                 if (reqp->accessError)
77                         return reqp->accessError;
78                 if (reqp->volumeError)
79                         return reqp->volumeError;
80                 if (reqp->rpcError)
81                         return reqp->rpcError;
82                 return error;
83         }
84
85         if (error < 0) error = CM_ERROR_TIMEDOUT;
86         else if (error == 30) error = CM_ERROR_READONLY;
87         else if (error == 20) error = CM_ERROR_NOTDIR;
88         else if (error == 13) error = CM_ERROR_NOACCESS;
89         else if (error == 2) error = CM_ERROR_NOSUCHFILE;
90         else if (error == 17            /* AIX */
91                  || error == 66         /* SunOS 4, Digital UNIX */
92                  || error == 93         /* Solaris 2, IRIX */
93                  || error == 247)       /* HP/UX */
94                 error = CM_ERROR_NOTEMPTY;
95         return error;
96 }
97
98 long cm_MapVLRPCError(long error, cm_req_t *reqp)
99 {
100         if (error == 0) return 0;
101
102         /* If we had to stop retrying, report our saved error code. */
103         if (reqp && error == CM_ERROR_TIMEDOUT) {
104                 if (reqp->accessError)
105                         return reqp->accessError;
106                 if (reqp->volumeError)
107                         return reqp->volumeError;
108                 if (reqp->rpcError)
109                         return reqp->rpcError;
110                 return error;
111         }
112
113         if (error < 0) error = CM_ERROR_TIMEDOUT;
114         else if (error == VL_NOENT) error = CM_ERROR_NOSUCHVOLUME;
115         return error;
116 }
117
118 cm_space_t *cm_GetSpace(void)
119 {
120         cm_space_t *tsp;
121
122         if (osi_Once(&cm_utilsOnce)) {
123                 lock_InitializeRWLock(&cm_utilsLock, "cm_utilsLock");
124                 osi_EndOnce(&cm_utilsOnce);
125         }
126         
127         lock_ObtainWrite(&cm_utilsLock);
128         if (tsp = cm_spaceListp) {
129                 cm_spaceListp = tsp->nextp;
130         }
131         else tsp = (cm_space_t *) malloc(sizeof(cm_space_t));
132         (void) memset(tsp, 0, sizeof(cm_space_t));
133         lock_ReleaseWrite(&cm_utilsLock);
134         
135         return tsp;
136 }
137
138 void cm_FreeSpace(cm_space_t *tsp)
139 {
140         lock_ObtainWrite(&cm_utilsLock);
141         tsp->nextp = cm_spaceListp;
142         cm_spaceListp = tsp;
143         lock_ReleaseWrite(&cm_utilsLock);
144 }