Mercurial > illumos > onarm
diff usr/src/cmd/cmd-inet/usr.sbin/in.talkd/table.c @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/cmd/cmd-inet/usr.sbin/in.talkd/table.c Tue Jun 02 18:56:50 2009 +0900 @@ -0,0 +1,285 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Copyright 2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T + * All Rights Reserved. + */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California. + * All Rights Reserved. + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ + +#pragma ident "@(#)table.c 1.8 05/06/12 SMI" + + +/* + * 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 <sys/time.h> +#include <string.h> +#include <stdio.h> +#include <malloc.h> +#include "talkd_impl.h" + +#define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ + +typedef struct table_entry TABLE_ENTRY; + +struct table_entry { + CTL_MSG request; + long time; + TABLE_ENTRY *next; + TABLE_ENTRY *last; +}; + +static struct timeval tp; +static TABLE_ENTRY *table = NULL; + +static void delete(TABLE_ENTRY *ptr); + +/* + * Look in the table for an invitation that matches the current + * request looking for an invitation. + */ + +CTL_MSG * +find_match(CTL_MSG *request) +{ + TABLE_ENTRY *ptr; + TABLE_ENTRY *prevp; + long current_time; + + (void) gettimeofday(&tp, NULL); + current_time = tp.tv_sec; + + ptr = table; + + if (debug) { + (void) printf("Entering Look-Up with : \n"); + print_request(request); + } + + while (ptr != NULL) { + + if ((ptr->time - current_time) > MAX_LIFE) { + /* the entry is too old */ + if (debug) { + (void) printf("Deleting expired entry : \n"); + print_request(&ptr->request); + } + prevp = ptr; + ptr = ptr->next; + delete(prevp); + continue; + } + + if (debug) + 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) { + return (&ptr->request); + } + + ptr = ptr->next; + } + + return (NULL); +} + +/* + * Look for an identical request, as opposed to a complimentary + * one as find_match does. + */ + +CTL_MSG * +find_request(CTL_MSG *request) +{ + TABLE_ENTRY *ptr; + TABLE_ENTRY *prevp; + long current_time; + + (void) gettimeofday(&tp, NULL); + 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. + */ + + ptr = table; + + if (debug) { + (void) printf("Entering find_request with : \n"); + print_request(request); + } + + while (ptr != NULL) { + + if ((ptr->time - current_time) > MAX_LIFE) { + /* the entry is too old */ + if (debug) { + (void) printf("Deleting expired entry : \n"); + print_request(&ptr->request); + } + prevp = ptr; + ptr = ptr->next; + delete(prevp); + continue; + } + + if (debug) + 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; + return (&ptr->request); + } + + ptr = ptr->next; + } + + return (NULL); +} + +void +insert_table(CTL_MSG *request, CTL_RESPONSE *response) +{ + TABLE_ENTRY *ptr; + long current_time; + + (void) gettimeofday(&tp, NULL); + current_time = tp.tv_sec; + + response->id_num = request->id_num = new_id(); + + /* + * Insert a new entry into the top of the list. + */ + ptr = (TABLE_ENTRY *) malloc(sizeof (TABLE_ENTRY)); + + if (ptr == NULL) { + print_error("malloc in insert_table"); + } + + ptr->time = current_time; + ptr->request = *request; + + ptr->next = table; + if (ptr->next != NULL) { + ptr->next->last = ptr; + } + ptr->last = NULL; + table = ptr; +} + +/* + * Generate a unique non-zero sequence number. + */ + +int +new_id(void) +{ + static int current_id = 0; + + current_id = (current_id + 1) % MAX_ID; + + /* 0 is reserved, helps to pick up bugs */ + if (current_id == 0) + current_id = 1; + + return (current_id); +} + +/* + * Delete the invitation with id 'id_num'. + */ + +int +delete_invite(int id_num) +{ + TABLE_ENTRY *ptr; + + ptr = table; + + if (debug) + (void) printf("Entering delete_invite with %d\n", id_num); + + while (ptr != NULL && ptr->request.id_num != id_num) { + if (debug) + print_request(&ptr->request); + ptr = ptr->next; + } + + if (ptr != NULL) { + delete(ptr); + return (SUCCESS); + } + + return (NOT_HERE); +} + +/* + * Classic delete from a double-linked list. + */ + +static void +delete(TABLE_ENTRY *ptr) +{ + if (debug) { + (void) printf("Deleting : "); + print_request(&ptr->request); + } + if (table == ptr) { + table = ptr->next; + } else if (ptr->last != NULL) { + ptr->last->next = ptr->next; + } + + if (ptr->next != NULL) { + ptr->next->last = ptr->last; + } + + free(ptr); +}