5521ba55dc1626c7ecd4cacbaca2cccbeb9cd837
[openafs.git] / src / butc / list.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 <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #include <rx/xdr.h>
16 #include <rx/rx.h>
17 #include <lock.h>
18 #include <lwp.h>
19 #include <afs/tcdata.h>
20
21 #include "error_macros.h"
22
23 /*extern int debugLevel;*/
24 static struct dumpNode *dumpQHeader;    /* ptr to head of the dumpNode list */
25 static struct dumpNode headNode;        /* the dummy header of the node list */
26 static afs_int32 maxTaskID;     /* the largest task Id allotted so far, this is never reused */
27
28 /* allocTaskId
29  *      allocate a dump (task) id
30  */
31 afs_int32
32 allocTaskId(void)
33 {
34     return (maxTaskID++);
35 }
36
37
38 /* initialize the node list used to keep track of the active dumps */
39 void
40 InitNodeList(afs_int32 portOffset)
41 {
42     maxTaskID = (portOffset * 1000) + 1;        /* this is the first task id alotted */
43     headNode.taskID = -1;
44     headNode.next = NULL;
45     headNode.dumps = (struct tc_dumpDesc *)0;
46     headNode.restores = (struct tc_restoreDesc *)0;
47     dumpQHeader = &headNode;    /* noone in the list to start with */
48 }
49
50 /* CreateNode
51  *      Create a <newNode> for the dump, put it in the list of active dumps
52  *      and return a pointer to it
53  * entry:
54  *      newNode - for return ptr
55  * exit:
56  *      newNode ptr set to point to a node.
57  */
58
59 void
60 CreateNode(struct dumpNode **newNode)
61 {
62     /* get space */
63     *newNode = (struct dumpNode *)(malloc(sizeof(struct dumpNode)));
64
65     memset(*newNode, 0, sizeof(struct dumpNode));
66
67     (*newNode)->next = dumpQHeader->next;
68     dumpQHeader->next = *newNode;
69     (*newNode)->taskID = allocTaskId();
70
71 /*  if (debugLevel) DisplayNode(*newNode); */
72 }
73
74 /* free the space allotted to the node with <taskID> */
75 void
76 FreeNode(afs_int32 taskID)
77 {
78     struct dumpNode *oldPtr, *newPtr, *curPtr;
79     int done;
80
81     curPtr = dumpQHeader;
82     oldPtr = dumpQHeader;
83     if (curPtr)
84         newPtr = dumpQHeader->next;
85     else
86         newPtr = NULL;
87     done = 0;
88     while ((!done) && (curPtr != NULL)) {
89         if (curPtr->taskID == taskID) {
90             done = 1;
91             oldPtr->next = newPtr;
92
93             /* free the node and its structures */
94             if (curPtr->dumpName)
95                 free(curPtr->dumpName);
96             if (curPtr->volumeSetName)
97                 free(curPtr->volumeSetName);
98             if (curPtr->restores)
99                 free(curPtr->restores);
100             if (curPtr->dumps)
101                 free(curPtr->dumps);
102             free(curPtr);
103         } else {
104             oldPtr = curPtr;
105             curPtr = newPtr;
106             if (newPtr)
107                 newPtr = newPtr->next;
108
109         }
110     }
111     return;
112
113 }
114
115 afs_int32
116 GetNthNode(afs_int32 aindex, afs_int32 *aresult)
117 {
118     struct dumpNode *tn;
119     int i;
120
121     tn = dumpQHeader->next;
122     for (i = 0;; i++) {
123         if (!tn)
124             return ENOENT;
125         /* see if this is the desired node ID */
126         if (i == aindex) {
127             *aresult = tn->taskID;
128             return 0;
129         }
130         /* otherwise, skip to next one and keep looking */
131         tn = tn->next;
132     }
133 }
134
135 /* return the node with <taskID> into <resultNode> */
136 afs_int32
137 GetNode(afs_int32 taskID, struct dumpNode **resultNode)
138 {
139     struct dumpNode *tmpPtr;
140     int done;
141
142     done = 0;
143     tmpPtr = dumpQHeader;
144     while ((!done) && (tmpPtr != NULL)) {
145         if (tmpPtr->taskID == taskID) {
146             *resultNode = tmpPtr;
147             done = 1;
148         } else
149             tmpPtr = tmpPtr->next;
150     }
151     if (done)
152         return 0;
153     else
154         return TC_NODENOTFOUND;
155 }