1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)table.c 5.2 (Berkeley) 3/13/86";
9: #endif not lint
10:
11: /*
12: * Routines to handle insertion, deletion, etc on the table
13: * of requests kept by the daemon. Nothing fancy here, linear
14: * search on a double-linked list. A time is kept with each
15: * entry so that overly old invitations can be eliminated.
16: *
17: * Consider this a mis-guided attempt at modularity
18: */
19: #include <stdio.h>
20: #include <sys/time.h>
21: #include <syslog.h>
22:
23: #include <protocols/talkd.h>
24:
25: #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */
26:
27: #define NIL ((TABLE_ENTRY *)0)
28:
29: extern int debug;
30: struct timeval tp;
31: struct timezone *txp;
32:
33: typedef struct table_entry TABLE_ENTRY;
34:
35: struct table_entry {
36: CTL_MSG request;
37: long time;
38: TABLE_ENTRY *next;
39: TABLE_ENTRY *last;
40: };
41:
42: TABLE_ENTRY *table = NIL;
43: CTL_MSG *find_request();
44: CTL_MSG *find_match();
45: char *malloc();
46:
47: /*
48: * Look in the table for an invitation that matches the current
49: * request looking for an invitation
50: */
51: CTL_MSG *
52: find_match(request)
53: register CTL_MSG *request;
54: {
55: register TABLE_ENTRY *ptr;
56: long current_time;
57:
58: gettimeofday(&tp, &txp);
59: current_time = tp.tv_sec;
60: if (debug)
61: print_request("find_match", request);
62: for (ptr = table; ptr != NIL; ptr = ptr->next) {
63: if ((ptr->time - current_time) > MAX_LIFE) {
64: /* the entry is too old */
65: if (debug)
66: print_request("deleting expired entry",
67: &ptr->request);
68: delete(ptr);
69: continue;
70: }
71: if (debug)
72: print_request("", &ptr->request);
73: if (strcmp(request->l_name, ptr->request.r_name) == 0 &&
74: strcmp(request->r_name, ptr->request.l_name) == 0 &&
75: ptr->request.type == LEAVE_INVITE)
76: return (&ptr->request);
77: }
78: return ((CTL_MSG *)0);
79: }
80:
81: /*
82: * Look for an identical request, as opposed to a complimentary
83: * one as find_match does
84: */
85: CTL_MSG *
86: find_request(request)
87: register CTL_MSG *request;
88: {
89: register TABLE_ENTRY *ptr;
90: long current_time;
91:
92: gettimeofday(&tp, &txp);
93: current_time = tp.tv_sec;
94: /*
95: * See if this is a repeated message, and check for
96: * out of date entries in the table while we are it.
97: */
98: if (debug)
99: print_request("find_request", request);
100: for (ptr = table; ptr != NIL; ptr = ptr->next) {
101: if ((ptr->time - current_time) > MAX_LIFE) {
102: /* the entry is too old */
103: if (debug)
104: print_request("deleting expired entry",
105: &ptr->request);
106: delete(ptr);
107: continue;
108: }
109: if (debug)
110: print_request("", &ptr->request);
111: if (strcmp(request->r_name, ptr->request.r_name) == 0 &&
112: strcmp(request->l_name, ptr->request.l_name) == 0 &&
113: request->type == ptr->request.type &&
114: request->pid == ptr->request.pid) {
115: /* update the time if we 'touch' it */
116: ptr->time = current_time;
117: return (&ptr->request);
118: }
119: }
120: return ((CTL_MSG *)0);
121: }
122:
123: insert_table(request, response)
124: CTL_MSG *request;
125: CTL_RESPONSE *response;
126: {
127: register TABLE_ENTRY *ptr;
128: long current_time;
129:
130: gettimeofday(&tp, &txp);
131: current_time = tp.tv_sec;
132: request->id_num = new_id();
133: response->id_num = htonl(request->id_num);
134: /* insert a new entry into the top of the list */
135: ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY));
136: if (ptr == NIL) {
137: syslog(LOG_ERR, "insert_table: Out of memory");
138: _exit(1);
139: }
140: ptr->time = current_time;
141: ptr->request = *request;
142: ptr->next = table;
143: if (ptr->next != NIL)
144: ptr->next->last = ptr;
145: ptr->last = NIL;
146: table = ptr;
147: }
148:
149: /*
150: * Generate a unique non-zero sequence number
151: */
152: new_id()
153: {
154: static int current_id = 0;
155:
156: current_id = (current_id + 1) % MAX_ID;
157: /* 0 is reserved, helps to pick up bugs */
158: if (current_id == 0)
159: current_id = 1;
160: return (current_id);
161: }
162:
163: /*
164: * Delete the invitation with id 'id_num'
165: */
166: delete_invite(id_num)
167: int id_num;
168: {
169: register TABLE_ENTRY *ptr;
170:
171: ptr = table;
172: if (debug)
173: syslog(LOG_DEBUG, "delete_invite(%d)", id_num);
174: for (ptr = table; ptr != NIL; ptr = ptr->next) {
175: if (ptr->request.id_num == id_num)
176: break;
177: if (debug)
178: print_request("", &ptr->request);
179: }
180: if (ptr != NIL) {
181: delete(ptr);
182: return (SUCCESS);
183: }
184: return (NOT_HERE);
185: }
186:
187: /*
188: * Classic delete from a double-linked list
189: */
190: delete(ptr)
191: register TABLE_ENTRY *ptr;
192: {
193:
194: if (debug)
195: print_request("delete", &ptr->request);
196: if (table == ptr)
197: table = ptr->next;
198: else if (ptr->last != NIL)
199: ptr->last->next = ptr->next;
200: if (ptr->next != NIL)
201: ptr->next->last = ptr->last;
202: free((char *)ptr);
203: }
Defined functions
Defined variables
sccsid
defined in line
8;
never used
table
defined in line
42; used 8 times
tp
defined in line
30; used 6 times
txp
defined in line
31; used 3 times
Defined struct's
Defined typedef's
Defined macros
NIL
defined in line
27; used 10 times