|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.