* Copyright (c) 1983 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)table.c 5.7 (Berkeley) 2/26/91";
* Routines to handle insertion, deletion, etc on the table
* of requests kept by the daemon. Nothing fancy here, linear
* search on a double-linked list. A time is kept with each
* entry so that overly old invitations can be eliminated.
* Consider this a mis-guided attempt at modularity
#include <protocols/talkd.h>
#define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */
#define NIL ((TABLE_ENTRY *)0)
typedef struct table_entry TABLE_ENTRY
;
TABLE_ENTRY
*table
= NIL
;
* Look in the table for an invitation that matches the current
* request looking for an invitation
register CTL_MSG
*request
;
register TABLE_ENTRY
*ptr
;
current_time
= tp
.tv_sec
;
print_request("find_match", request
);
for (ptr
= table
; ptr
!= NIL
; ptr
= ptr
->next
) {
if ((ptr
->time
- current_time
) > MAX_LIFE
) {
/* the entry is too old */
print_request("deleting expired entry",
print_request("", &ptr
->request
);
if (strcmp(request
->l_name
, ptr
->request
.r_name
) == 0 &&
strcmp(request
->r_name
, ptr
->request
.l_name
) == 0 &&
ptr
->request
.type
== LEAVE_INVITE
)
* Look for an identical request, as opposed to a complimentary
register CTL_MSG
*request
;
register TABLE_ENTRY
*ptr
;
current_time
= tp
.tv_sec
;
* See if this is a repeated message, and check for
* out of date entries in the table while we are it.
print_request("find_request", request
);
for (ptr
= table
; ptr
!= NIL
; ptr
= ptr
->next
) {
if ((ptr
->time
- current_time
) > MAX_LIFE
) {
/* the entry is too old */
print_request("deleting expired entry",
print_request("", &ptr
->request
);
if (strcmp(request
->r_name
, ptr
->request
.r_name
) == 0 &&
strcmp(request
->l_name
, ptr
->request
.l_name
) == 0 &&
request
->type
== ptr
->request
.type
&&
request
->pid
== ptr
->request
.pid
) {
/* update the time if we 'touch' it */
ptr
->time
= current_time
;
insert_table(request
, response
)
register TABLE_ENTRY
*ptr
;
current_time
= tp
.tv_sec
;
request
->id_num
= new_id();
response
->id_num
= htonl(request
->id_num
);
/* insert a new entry into the top of the list */
ptr
= (TABLE_ENTRY
*)malloc(sizeof(TABLE_ENTRY
));
syslog(LOG_ERR
, "insert_table: Out of memory");
ptr
->time
= current_time
;
* Generate a unique non-zero sequence number
static int current_id
= 0;
current_id
= (current_id
+ 1) % MAX_ID
;
/* 0 is reserved, helps to pick up bugs */
* Delete the invitation with id 'id_num'
register TABLE_ENTRY
*ptr
;
syslog(LOG_DEBUG
, "delete_invite(%d)", id_num
);
for (ptr
= table
; ptr
!= NIL
; ptr
= ptr
->next
) {
if (ptr
->request
.id_num
== id_num
)
print_request("", &ptr
->request
);
* Classic delete from a double-linked list
register TABLE_ENTRY
*ptr
;
print_request("delete", &ptr
->request
);
else if (ptr
->last
!= NIL
)
ptr
->last
->next
= ptr
->next
;
ptr
->next
->last
= ptr
->last
;