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