xref: /csrg-svn/libexec/talkd/table.c (revision 34360)
122399Sdist /*
222399Sdist  * Copyright (c) 1983 Regents of the University of California.
3*34360Sbostic  * All rights reserved.
4*34360Sbostic  *
5*34360Sbostic  * Redistribution and use in source and binary forms are permitted
6*34360Sbostic  * provided that this notice is preserved and that due credit is given
7*34360Sbostic  * to the University of California at Berkeley. The name of the University
8*34360Sbostic  * may not be used to endorse or promote products derived from this
9*34360Sbostic  * software without specific prior written permission. This software
10*34360Sbostic  * is provided ``as is'' without express or implied warranty.
1122399Sdist  */
1222399Sdist 
1316366Skarels #ifndef lint
14*34360Sbostic static char sccsid[] = "@(#)table.c	5.4 (Berkeley) 05/20/88";
15*34360Sbostic #endif /* not lint */
1616356Skarels 
1716366Skarels /*
1816366Skarels  * Routines to handle insertion, deletion, etc on the table
1916366Skarels  * of requests kept by the daemon. Nothing fancy here, linear
2016366Skarels  * search on a double-linked list. A time is kept with each
2116366Skarels  * entry so that overly old invitations can be eliminated.
2216366Skarels  *
2316366Skarels  * Consider this a mis-guided attempt at modularity
2416356Skarels  */
2516366Skarels #include <stdio.h>
2616366Skarels #include <sys/time.h>
2726840Smckusick #include <syslog.h>
2832103Smckusick #include <sys/param.h>
2916356Skarels 
3026840Smckusick #include <protocols/talkd.h>
3116356Skarels 
3216366Skarels #define MAX_ID 16000	/* << 2^15 so I don't have sign troubles */
3316356Skarels 
3416366Skarels #define NIL ((TABLE_ENTRY *)0)
3516356Skarels 
3616366Skarels extern	int debug;
3716366Skarels struct	timeval tp;
3816366Skarels struct	timezone *txp;
3916356Skarels 
4016356Skarels typedef struct table_entry TABLE_ENTRY;
4116356Skarels 
4216356Skarels struct table_entry {
4316366Skarels 	CTL_MSG request;
4416366Skarels 	long	time;
4516366Skarels 	TABLE_ENTRY *next;
4616366Skarels 	TABLE_ENTRY *last;
4716356Skarels };
4816356Skarels 
4926840Smckusick TABLE_ENTRY *table = NIL;
5016356Skarels CTL_MSG *find_request();
5116356Skarels CTL_MSG *find_match();
5216366Skarels char	*malloc();
5316356Skarels 
5416366Skarels /*
5516366Skarels  * Look in the table for an invitation that matches the current
5616366Skarels  * request looking for an invitation
5716366Skarels  */
5816366Skarels CTL_MSG *
5916366Skarels find_match(request)
6026840Smckusick 	register CTL_MSG *request;
6116356Skarels {
6226840Smckusick 	register TABLE_ENTRY *ptr;
6316366Skarels 	long current_time;
6416356Skarels 
6516366Skarels 	gettimeofday(&tp, &txp);
6616366Skarels 	current_time = tp.tv_sec;
6726840Smckusick 	if (debug)
6826840Smckusick 		print_request("find_match", request);
6916366Skarels 	for (ptr = table; ptr != NIL; ptr = ptr->next) {
7016366Skarels 		if ((ptr->time - current_time) > MAX_LIFE) {
7116366Skarels 			/* the entry is too old */
7226840Smckusick 			if (debug)
7326840Smckusick 				print_request("deleting expired entry",
7426840Smckusick 				    &ptr->request);
7516366Skarels 			delete(ptr);
7616366Skarels 			continue;
7716366Skarels 		}
7816366Skarels 		if (debug)
7926840Smckusick 			print_request("", &ptr->request);
8016366Skarels 		if (strcmp(request->l_name, ptr->request.r_name) == 0 &&
8116366Skarels 		    strcmp(request->r_name, ptr->request.l_name) == 0 &&
8216366Skarels 		     ptr->request.type == LEAVE_INVITE)
8316366Skarels 			return (&ptr->request);
8416356Skarels 	}
8516366Skarels 	return ((CTL_MSG *)0);
8616356Skarels }
8716356Skarels 
8816366Skarels /*
8916366Skarels  * Look for an identical request, as opposed to a complimentary
9016366Skarels  * one as find_match does
9116366Skarels  */
9216366Skarels CTL_MSG *
9316366Skarels find_request(request)
9426840Smckusick 	register CTL_MSG *request;
9516356Skarels {
9626840Smckusick 	register TABLE_ENTRY *ptr;
9716366Skarels 	long current_time;
9816356Skarels 
9916366Skarels 	gettimeofday(&tp, &txp);
10016366Skarels 	current_time = tp.tv_sec;
10116366Skarels 	/*
10216366Skarels 	 * See if this is a repeated message, and check for
10316366Skarels 	 * out of date entries in the table while we are it.
10416356Skarels 	 */
10526840Smckusick 	if (debug)
10626840Smckusick 		print_request("find_request", request);
10716366Skarels 	for (ptr = table; ptr != NIL; ptr = ptr->next) {
10816366Skarels 		if ((ptr->time - current_time) > MAX_LIFE) {
10916366Skarels 			/* the entry is too old */
11026840Smckusick 			if (debug)
11126840Smckusick 				print_request("deleting expired entry",
11226840Smckusick 				    &ptr->request);
11316366Skarels 			delete(ptr);
11416366Skarels 			continue;
11516366Skarels 		}
11616366Skarels 		if (debug)
11726840Smckusick 			print_request("", &ptr->request);
11816366Skarels 		if (strcmp(request->r_name, ptr->request.r_name) == 0 &&
11916366Skarels 		    strcmp(request->l_name, ptr->request.l_name) == 0 &&
12016366Skarels 		    request->type == ptr->request.type &&
12116366Skarels 		    request->pid == ptr->request.pid) {
12216366Skarels 			/* update the time if we 'touch' it */
12316366Skarels 			ptr->time = current_time;
12416366Skarels 			return (&ptr->request);
12516366Skarels 		}
12616356Skarels 	}
12716366Skarels 	return ((CTL_MSG *)0);
12816356Skarels }
12916356Skarels 
13016356Skarels insert_table(request, response)
13116366Skarels 	CTL_MSG *request;
13216366Skarels 	CTL_RESPONSE *response;
13316356Skarels {
13426840Smckusick 	register TABLE_ENTRY *ptr;
13516366Skarels 	long current_time;
13616356Skarels 
13716366Skarels 	gettimeofday(&tp, &txp);
13816366Skarels 	current_time = tp.tv_sec;
13926840Smckusick 	request->id_num = new_id();
14026840Smckusick 	response->id_num = htonl(request->id_num);
14116356Skarels 	/* insert a new entry into the top of the list */
14216366Skarels 	ptr = (TABLE_ENTRY *)malloc(sizeof(TABLE_ENTRY));
14316366Skarels 	if (ptr == NIL) {
14426840Smckusick 		syslog(LOG_ERR, "insert_table: Out of memory");
14526840Smckusick 		_exit(1);
14616366Skarels 	}
14716366Skarels 	ptr->time = current_time;
14816366Skarels 	ptr->request = *request;
14916366Skarels 	ptr->next = table;
15016366Skarels 	if (ptr->next != NIL)
15116366Skarels 		ptr->next->last = ptr;
15216366Skarels 	ptr->last = NIL;
15316366Skarels 	table = ptr;
15416356Skarels }
15516356Skarels 
15616366Skarels /*
15716366Skarels  * Generate a unique non-zero sequence number
15816366Skarels  */
15916356Skarels new_id()
16016356Skarels {
16116366Skarels 	static int current_id = 0;
16216356Skarels 
16316366Skarels 	current_id = (current_id + 1) % MAX_ID;
16416356Skarels 	/* 0 is reserved, helps to pick up bugs */
16516366Skarels 	if (current_id == 0)
16616366Skarels 		current_id = 1;
16716366Skarels 	return (current_id);
16816356Skarels }
16916356Skarels 
17016366Skarels /*
17116366Skarels  * Delete the invitation with id 'id_num'
17216366Skarels  */
17316356Skarels delete_invite(id_num)
17416366Skarels 	int id_num;
17516356Skarels {
17626840Smckusick 	register TABLE_ENTRY *ptr;
17716356Skarels 
17816366Skarels 	ptr = table;
17916366Skarels 	if (debug)
18026840Smckusick 		syslog(LOG_DEBUG, "delete_invite(%d)", id_num);
18116366Skarels 	for (ptr = table; ptr != NIL; ptr = ptr->next) {
18216366Skarels 		if (ptr->request.id_num == id_num)
18316366Skarels 			break;
18416366Skarels 		if (debug)
18526840Smckusick 			print_request("", &ptr->request);
18616366Skarels 	}
18716366Skarels 	if (ptr != NIL) {
18816366Skarels 		delete(ptr);
18916366Skarels 		return (SUCCESS);
19016366Skarels 	}
19116366Skarels 	return (NOT_HERE);
19216356Skarels }
19316356Skarels 
19416366Skarels /*
19516366Skarels  * Classic delete from a double-linked list
19616366Skarels  */
19716356Skarels delete(ptr)
19826840Smckusick 	register TABLE_ENTRY *ptr;
19916356Skarels {
20016356Skarels 
20126840Smckusick 	if (debug)
20226840Smckusick 		print_request("delete", &ptr->request);
20316366Skarels 	if (table == ptr)
20416366Skarels 		table = ptr->next;
20516366Skarels 	else if (ptr->last != NIL)
20616366Skarels 		ptr->last->next = ptr->next;
20716366Skarels 	if (ptr->next != NIL)
20816366Skarels 		ptr->next->last = ptr->last;
20916366Skarels 	free((char *)ptr);
21016356Skarels }
211