|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: static char sccsid[] = "@(#)table.c 5.5 (Berkeley) 6/18/88";
20: #endif /* not lint */
21:
22: /*
23: * Routines to handle insertion, deletion, etc on the table
24: * of requests kept by the daemon. Nothing fancy here, linear
25: * search on a double-linked list. A time is kept with each
26: * entry so that overly old invitations can be eliminated.
27: *
28: * Consider this a mis-guided attempt at modularity
29: */
30: #include <stdio.h>
31: #include <sys/time.h>
32: #include <syslog.h>
33: #include <sys/param.h>
34:
35: #include <protocols/talkd.h>
36:
37: #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */
38:
39: #define NIL ((TABLE_ENTRY *)0)
40:
41: extern int debug;
42: struct timeval tp;
43: struct timezone *txp;
44:
45: typedef struct table_entry TABLE_ENTRY;
46:
47: struct table_entry {
48: CTL_MSG request;
49: long time;
50: TABLE_ENTRY *next;
51: TABLE_ENTRY *last;
52: };
53:
54: TABLE_ENTRY *table = NIL;
55: CTL_MSG *find_request();
56: CTL_MSG *find_match();
57: char *malloc();
58:
59: /*
60: * Look in the table for an invitation that matches the current
61: * request looking for an invitation
62: */
63: CTL_MSG *
64: find_match(request)
65: register CTL_MSG *request;
66: {
67: register TABLE_ENTRY *ptr;
68: long current_time;
69:
70: gettimeofday(&tp, &txp);
71: current_time = tp.tv_sec;
72: if (debug)
73: print_request("find_match", request);
74: for (ptr = table; ptr != NIL; ptr = ptr->next) {
75: if ((ptr->time - current_time) > MAX_LIFE) {
76: /* the entry is too old */
77: if (debug)
78: print_request("deleting expired entry",
79: &ptr->request);
80: delete(ptr);
81: continue;
82: }
83: if (debug)
84: print_request("", &ptr->request);
85: if (strcmp(request->l_name, ptr->request.r_name) == 0 &&
86: strcmp(request->r_name, ptr->request.l_name) == 0 &&
87: ptr->request.type == LEAVE_INVITE)
88: return (&ptr->request);
89: }
90: return ((CTL_MSG *)0);
91: }
92:
93: /*
94: * Look for an identical request, as opposed to a complimentary
95: * one as find_match does
96: */
97: CTL_MSG *
98: find_request(request)
99: register CTL_MSG *request;
100: {
101: register TABLE_ENTRY *ptr;
102: long current_time;
103:
104: gettimeofday(&tp, &txp);
105: current_time = tp.tv_sec;
106: /*
107: * See if this is a repeated message, and check for
108: * out of date entries in the table while we are it.
109: */
110: if (debug)
111: print_request("find_request", request);
112: for (ptr = table; ptr != NIL; ptr = ptr->next) {
113: if ((ptr->time - current_time) > MAX_LIFE) {
114: /* the entry is too old */
115: if (debug)
116: print_request("deleting expired entry",
117: &ptr->request);
118: delete(ptr);
119: continue;
120: }
121: if (debug)
122: print_request("", &ptr->request);
123: if (strcmp(request->r_name, ptr->request.r_name) == 0 &&
124: strcmp(request->l_name, ptr->request.l_name) == 0 &&
125: request->type == ptr->request.type &&
126: request->pid == ptr->request.pid) {
127: /* update the time if we 'touch' it */
128: ptr->time = current_time;
129: return (&ptr->request);
130: }
131: }
132: return ((CTL_MSG *)0);
133: }
134:
135: insert_table(request, response)
136: CTL_MSG *request;
137: CTL_RESPONSE *response;
138: {
139: register TABLE_ENTRY *ptr;
140: long current_time;
141:
142: gettimeofday(&tp, &txp);
143: current_time = tp.tv_sec;
144: request->id_num = new_id();
145: response->id_num = htonl(request->id_num);
146: /* insert a new entry into the top of the list */
147: ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY));
148: if (ptr == NIL) {
149: syslog(LOG_ERR, "insert_table: Out of memory");
150: _exit(1);
151: }
152: ptr->time = current_time;
153: ptr->request = *request;
154: ptr->next = table;
155: if (ptr->next != NIL)
156: ptr->next->last = ptr;
157: ptr->last = NIL;
158: table = ptr;
159: }
160:
161: /*
162: * Generate a unique non-zero sequence number
163: */
164: new_id()
165: {
166: static int current_id = 0;
167:
168: current_id = (current_id + 1) % MAX_ID;
169: /* 0 is reserved, helps to pick up bugs */
170: if (current_id == 0)
171: current_id = 1;
172: return (current_id);
173: }
174:
175: /*
176: * Delete the invitation with id 'id_num'
177: */
178: delete_invite(id_num)
179: int id_num;
180: {
181: register TABLE_ENTRY *ptr;
182:
183: ptr = table;
184: if (debug)
185: syslog(LOG_DEBUG, "delete_invite(%d)", id_num);
186: for (ptr = table; ptr != NIL; ptr = ptr->next) {
187: if (ptr->request.id_num == id_num)
188: break;
189: if (debug)
190: print_request("", &ptr->request);
191: }
192: if (ptr != NIL) {
193: delete(ptr);
194: return (SUCCESS);
195: }
196: return (NOT_HERE);
197: }
198:
199: /*
200: * Classic delete from a double-linked list
201: */
202: delete(ptr)
203: register TABLE_ENTRY *ptr;
204: {
205:
206: if (debug)
207: print_request("delete", &ptr->request);
208: if (table == ptr)
209: table = ptr->next;
210: else if (ptr->last != NIL)
211: ptr->last->next = ptr->next;
212: if (ptr->next != NIL)
213: ptr->next->last = ptr->last;
214: free((char *)ptr);
215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.