afsconfig-and-rcsid-all-around-20010705
[openafs.git] / src / libadmin / vos / lockprocs.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 <afsconfig.h>
12
13 RCSID("$Header$");
14
15 #include "lockprocs.h"
16 #ifdef HAVE_STRINGS_H
17 #include <strings.h>
18 #else
19 #ifdef HAVE_STRING_H
20 #include <string.h>
21 #endif
22 #endif
23
24 /* Finds an index in VLDB entry that matches the volume type, server, and partition.
25  * If type is zero, will match first index of ANY type (RW, BK, or RO).
26  * If server is zero, will match first index of ANY server and partition 
27  * Zero is a valid partition field.
28  */
29 static int FindIndex(
30   afs_cell_handle_p cellHandle,
31   struct nvldbentry *entry,
32   afs_int32 server,
33   afs_int32 part,
34   afs_int32 type)
35 {
36     afs_status_t tst = 0;
37     int e;
38     int equal = 0;
39
40     for (e=0; (e < entry->nServers) && !tst ; e++) {
41         if (!type || (entry->serverFlags[e] & type)) {
42             VLDB_IsSameAddrs(cellHandle, entry->serverNumber[e], server,
43                              &equal, &tst);
44             if ((!server || (entry->serverPartition[e] == part)) &&
45                 (!server || equal)) {
46                 break;
47             }
48             if (type == ITSRWVOL) {
49                 /* quit when we are looking for RW entry (there's only 1) */
50                 return -1;
51             }
52         }
53     }
54
55     if (e >= entry->nServers) {
56        return -1;    /* Didn't find it */
57     }
58
59     return e;        /* return the index */
60 }
61
62 /* Changes the rw site only */
63 static void SetAValue (
64   afs_cell_handle_p cellHandle,
65   struct nvldbentry *entry,
66   afs_int32 oserver,
67   afs_int32 opart,
68   afs_int32 nserver,
69   afs_int32 npart,
70   afs_int32 type)
71 {
72     int e;
73
74     e = FindIndex(cellHandle, entry, oserver, opart, type);
75     if (e == -1)
76        return;              /* If didn't find it, just return */
77
78     entry->serverNumber[e]    = nserver;
79     entry->serverPartition[e] = npart;
80
81     /* Now move rest of entries up */
82     if ((nserver == 0L) && (npart == 0L)) {
83        for (e++; e<entry->nServers; e++) {
84           entry->serverNumber[e-1]    = entry->serverNumber[e];
85           entry->serverPartition[e-1] = entry->serverPartition[e];
86           entry->serverFlags[e-1]     = entry->serverFlags[e];
87        }
88     }
89 }
90
91 /* Changes the RW site only */
92 void Lp_SetRWValue (
93   afs_cell_handle_p cellHandle,
94   struct nvldbentry *entry,
95   afs_int32 oserver,
96   afs_int32 opart,
97   afs_int32 nserver,
98   afs_int32 npart)
99 {
100     SetAValue (cellHandle, entry, oserver, opart, nserver, npart, ITSRWVOL);
101 }
102
103 /* Changes the RO site only */
104 void Lp_SetROValue(
105   afs_cell_handle_p cellHandle,
106   struct nvldbentry *entry,
107   afs_int32 oserver,
108   afs_int32 opart,
109   afs_int32 nserver,
110   afs_int32 npart)
111 {
112     SetAValue (cellHandle, entry, oserver, opart, nserver, npart, ITSROVOL);
113 }
114
115 /* Returns success if this server and partition matches the RW entry */
116 int Lp_Match(
117   afs_cell_handle_p cellHandle,
118   struct nvldbentry *entry,
119   afs_int32 server,
120   afs_int32 part,
121   afs_status_p st)
122 {
123     if (FindIndex(cellHandle, entry, server, part, ITSRWVOL) == -1)
124        return 0;
125     return 1;
126 }
127
128 /* Return the index of the RO entry (plus 1) if it exists, else return 0 */
129 int Lp_ROMatch(
130   afs_cell_handle_p cellHandle,
131   struct nvldbentry *entry,
132   afs_int32 server,
133   afs_int32 part,
134   afs_status_p st)
135 {
136    return (FindIndex(cellHandle, entry,server,part,ITSROVOL) + 1);
137 }
138
139 /* Return the index of the RW entry if it exists, else return -1 */
140 int Lp_GetRwIndex(
141   afs_cell_handle_p cellHandle,
142   struct nvldbentry *entry,
143   afs_status_p st)
144 {
145     return (FindIndex(cellHandle, entry,0,0,ITSRWVOL));
146 }
147
148 /*initialize queue pointed by <ahead>*/
149 void Lp_QInit(
150   struct qHead *ahead)
151 {
152    ahead->count = 0;
153    ahead->next  = (struct aqueue *)0;
154 }
155
156 /*add <elem> in front of queue <ahead> */
157 void Lp_QAdd(
158   struct qHead *ahead,
159   struct aqueue *elem)
160 {
161     struct aqueue *temp;
162
163     if(ahead->count == 0) {
164         ahead->count += 1;
165         ahead->next = elem;
166         elem->next = (struct aqueue *)0;
167     }
168     else {
169         temp = ahead->next;
170         ahead->count += 1;
171         ahead->next = elem;
172         elem->next = temp;
173     }
174 }
175
176 int Lp_QScan(
177   struct qHead *ahead,
178   afs_int32 id,
179   int *success,
180   struct aqueue **elem,
181   afs_status_p st)
182 {
183     struct aqueue *cptr;
184
185     cptr = ahead->next;
186     while(cptr != (struct aqueue *)0) {
187         if(cptr->ids[RWVOL] == id) {
188             *success = 1;
189             *elem = cptr;
190             return 0;
191         }
192         cptr = cptr->next;
193     }
194     *success = 0;
195     return 0;
196 }
197
198 /*return the element in the beginning of the queue <ahead>, free
199 *the space used by that element . <success> indicates if enumeration was ok*/
200 void Lp_QEnumerate(
201   struct qHead *ahead,
202   int *success,
203   struct aqueue *elem,
204   afs_status_p st)
205 {
206     int i;
207     struct aqueue *temp;
208
209     if(ahead->count > 0) {/*more elements left */
210         ahead->count -= 1;
211         temp = ahead->next;
212         ahead->next = ahead->next->next;
213         strncpy(elem->name,temp->name,VOLSER_OLDMAXVOLNAME);
214         for(i= 0; i < 3; i++){
215             elem->ids[i] = temp->ids[i];
216             elem->copyDate[i] = temp->copyDate[i];
217             elem->isValid[i] = temp->isValid[i];
218         }
219         elem->next = (struct aqueue *)0;
220         *success = 1;
221         free(temp);
222     }
223     else /*queue is empty*/
224         *success = 0;
225 }