cleanup-licensing-and-transarc-references-20030309
[openafs.git] / src / WINNT / client_osi / osifd.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 /* Copyright (C) 1994 Cazamar Systems, Inc. */
11
12
13 #include <afs/param.h>
14 #include <afs/stds.h>
15
16 #ifndef DJGPP
17 #include <windows.h>
18 #include <rpc.h>
19 #include "dbrpc.h"
20 #endif /* !DJGPP */
21 #include <malloc.h>
22 #include "osi.h"
23 #include <assert.h>
24
25 static Crit_Sec osi_fdCS;
26 osi_fd_t *osi_allFDs;
27 osi_fdType_t *osi_allFDTypes;
28 long osi_nextFD = 0;
29
30 osi_fdOps_t osi_TypeFDOps = {
31         osi_FDTypeCreate,
32 #ifndef DJGPP
33         osi_FDTypeGetInfo,
34 #endif
35         osi_FDTypeClose
36 };
37
38 /* called while holding osi_fdCS, returns named type or null pointer */
39 osi_fdType_t *osi_FindFDType(char *namep)
40 {
41         osi_fdType_t *ftp;
42
43         for(ftp = osi_allFDTypes; ftp; ftp = (osi_fdType_t *) osi_QNext(&ftp->q)) {
44                 if (strcmp(ftp->namep, namep) == 0) break;
45         }
46
47         return ftp;
48 }
49
50 long osi_UnregisterFDType(char *namep)
51 {
52         osi_fdType_t *ftp;
53         osi_fdTypeFormat_t *ffp;
54         osi_fdTypeFormat_t *nffp;
55
56         /* check for dup name */
57         thrd_EnterCrit(&osi_fdCS);
58         ftp = osi_FindFDType(namep);
59         if (!ftp) return -1;
60         
61         /* free subsidiary storage, and remove from list */
62         free(ftp->namep);
63         osi_QRemove((osi_queue_t **) &osi_allFDTypes, &ftp->q);
64         
65         /* free format structs */
66         for(ffp = ftp->formatListp; ffp; ffp=nffp) {
67                 nffp = ffp->nextp;
68                 free(ffp->labelp);
69                 free(ffp);
70         }
71
72         /* free main storage */
73         free(ftp);
74
75         /* cleanup and go */
76         thrd_LeaveCrit(&osi_fdCS);
77         return 0;
78 }
79
80 osi_fdType_t *osi_RegisterFDType(char *namep, osi_fdOps_t *opsp, void *datap)
81 {
82         osi_fdType_t *ftp;
83
84         /* check for dup name */
85         thrd_EnterCrit(&osi_fdCS);
86         osi_assertx(osi_FindFDType(namep) == NULL, "registering duplicate iteration type");
87
88         ftp = (osi_fdType_t *) malloc(sizeof(*ftp));
89         
90         ftp->namep = (char *) malloc(strlen(namep)+1);
91         strcpy(ftp->namep, namep);
92
93         ftp->rockp = datap;
94
95         ftp->opsp = opsp;
96
97         ftp->formatListp = NULL;
98
99         osi_QAdd((osi_queue_t **) &osi_allFDTypes, &ftp->q);
100         thrd_LeaveCrit(&osi_fdCS);
101
102         return ftp;
103 }
104
105 osi_AddFDFormatInfo(osi_fdType_t *typep, long region, long index,
106         char *labelp, long format)
107 {
108         osi_fdTypeFormat_t *formatp;
109
110         formatp = (osi_fdTypeFormat_t *) malloc(sizeof(*formatp));
111
112         formatp->labelp = (char *) malloc(strlen(labelp) + 1);
113         strcpy(formatp->labelp, labelp);
114
115         formatp->format = format;
116
117         /* now copy index info */
118         formatp->region = region;
119         formatp->index = index;
120
121         /* thread on the list when done */
122         thrd_EnterCrit(&osi_fdCS);
123         formatp->nextp = typep->formatListp;
124         typep->formatListp = formatp;
125         thrd_LeaveCrit(&osi_fdCS);
126
127         /* all done */
128         return 0;
129 }
130
131 osi_InitFD(void) {
132         static osi_once_t once;
133
134         if (!osi_Once(&once)) return 0;
135
136         osi_allFDs = NULL;
137         osi_allFDTypes = NULL;
138         thrd_InitCrit(&osi_fdCS);
139
140         /* now, initialize the types system by adding a type
141          * iteration operator
142          */
143         osi_RegisterFDType("type", &osi_TypeFDOps, NULL);
144
145         osi_EndOnce(&once);
146
147         return 0;
148 }
149
150 osi_fd_t *osi_AllocFD(char *namep)
151 {
152         osi_fd_t *fdp;
153         osi_fdType_t *fdTypep;
154         long code;
155
156         /* initialize for failure */
157         fdp = NULL;
158         
159         thrd_EnterCrit(&osi_fdCS);
160         fdTypep = osi_FindFDType(namep);
161         if (fdTypep) {
162                 code = (fdTypep->opsp->Create)(fdTypep, &fdp);
163                 if (code == 0) {
164                         fdp->fd = ++osi_nextFD;
165                         fdp->opsp = fdTypep->opsp;
166                         osi_QAdd((osi_queue_t **) &osi_allFDs, &fdp->q);
167                 }
168                 else fdp = NULL;
169         }
170         thrd_LeaveCrit(&osi_fdCS);
171
172         return fdp;
173 }
174
175 osi_fd_t *osi_FindFD(long fd)
176 {
177         osi_fd_t *fdp;
178
179         thrd_EnterCrit(&osi_fdCS);
180         for(fdp = osi_allFDs; fdp; fdp = (osi_fd_t *) osi_QNext(&fdp->q)) {
181                 if (fdp->fd == fd) break;
182         }
183         thrd_LeaveCrit(&osi_fdCS);
184
185         return fdp;
186 }
187
188 osi_CloseFD(osi_fd_t *fdp)
189 {
190         long code;
191
192         thrd_EnterCrit(&osi_fdCS);
193         osi_QRemove((osi_queue_t **) &osi_allFDs, &fdp->q);
194         thrd_LeaveCrit(&osi_fdCS);
195
196         /* this call frees the FD's storage, so make sure everything is unthreaded
197          * before here.
198          */
199         code = (fdp->opsp->Close)(fdp);
200
201         return code;
202 }
203
204
205 /* now we have the fd type operations */
206 long osi_FDTypeCreate(osi_fdType_t *fdTypep, osi_fd_t **outpp)
207 {
208         osi_typeFD_t *fdp;
209
210         fdp = (osi_typeFD_t *) malloc(sizeof(*fdp));
211
212         fdp->curp = osi_allFDTypes;
213
214         *outpp = &fdp->fd;
215         return 0;
216 }
217
218
219 #ifndef DJGPP
220 long osi_FDTypeGetInfo(osi_fd_t *ifdp, osi_remGetInfoParms_t *outp)
221 {
222         osi_typeFD_t *fdp;
223         osi_fdType_t *typep;
224
225         fdp = (osi_typeFD_t *) ifdp;
226
227         if (typep = fdp->curp) {
228                 /* still more stuff left, copy out name move to the next */
229                 outp->icount = 0;
230                 outp->scount = 1;
231                 strcpy(outp->sdata[0], typep->namep);
232                 thrd_EnterCrit(&osi_fdCS);
233                 fdp->curp = (osi_fdType_t *) osi_QNext(&typep->q);
234                 thrd_LeaveCrit(&osi_fdCS);
235                 return 0;
236         }
237         else {
238                 /* otherwise we've hit EOF */
239                 return OSI_DBRPC_EOF;
240         }
241 }
242 #endif /* !DJGPP */
243
244 long osi_FDTypeClose(osi_fd_t *ifdp)
245 {
246         osi_typeFD_t *fdp;
247
248         fdp = (osi_typeFD_t *) ifdp;
249
250         free((void *)fdp);
251
252         return 0;
253 }
254