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