|
|
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.