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