1*56577Sbostic /* 2*56577Sbostic * Copyright (c) 1983 Regents of the University of California. 3*56577Sbostic * All rights reserved. The Berkeley software License Agreement 4*56577Sbostic * specifies the terms and conditions for redistribution. 5*56577Sbostic */ 6*56577Sbostic 7*56577Sbostic #ifndef lint 8*56577Sbostic static char sccsid[] = "@(#)process.c 5.2 (Berkeley) 6/8/85"; 9*56577Sbostic #endif not lint 10*56577Sbostic 11*56577Sbostic /* 12*56577Sbostic * process.c handles the requests, which can be of three types: 13*56577Sbostic * ANNOUNCE - announce to a user that a talk is wanted 14*56577Sbostic * LEAVE_INVITE - insert the request into the table 15*56577Sbostic * LOOK_UP - look up to see if a request is waiting in 16*56577Sbostic * in the table for the local user 17*56577Sbostic * DELETE - delete invitation 18*56577Sbostic */ 19*56577Sbostic #include "ctl.h" 20*56577Sbostic #include <sys/stat.h> 21*56577Sbostic #include <stdio.h> 22*56577Sbostic 23*56577Sbostic char *strcpy(); 24*56577Sbostic CTL_MSG *find_request(); 25*56577Sbostic CTL_MSG *find_match(); 26*56577Sbostic 27*56577Sbostic process_request(request, response) 28*56577Sbostic CTL_MSG *request; 29*56577Sbostic CTL_RESPONSE *response; 30*56577Sbostic { 31*56577Sbostic CTL_MSG *ptr; 32*56577Sbostic 33*56577Sbostic response->type = request->type; 34*56577Sbostic response->id_num = 0; 35*56577Sbostic 36*56577Sbostic switch (request->type) { 37*56577Sbostic 38*56577Sbostic case ANNOUNCE : 39*56577Sbostic do_announce(request, response); 40*56577Sbostic break; 41*56577Sbostic 42*56577Sbostic case LEAVE_INVITE : 43*56577Sbostic ptr = find_request(request); 44*56577Sbostic if (ptr != (CTL_MSG *) 0) { 45*56577Sbostic response->id_num = ptr->id_num; 46*56577Sbostic response->answer = SUCCESS; 47*56577Sbostic } else 48*56577Sbostic insert_table(request, response); 49*56577Sbostic break; 50*56577Sbostic 51*56577Sbostic case LOOK_UP : 52*56577Sbostic ptr = find_match(request); 53*56577Sbostic if (ptr != (CTL_MSG *) 0) { 54*56577Sbostic response->id_num = ptr->id_num; 55*56577Sbostic response->addr = ptr->addr; 56*56577Sbostic response->answer = SUCCESS; 57*56577Sbostic } else 58*56577Sbostic response->answer = NOT_HERE; 59*56577Sbostic break; 60*56577Sbostic 61*56577Sbostic case DELETE : 62*56577Sbostic response->answer = delete_invite(request->id_num); 63*56577Sbostic break; 64*56577Sbostic 65*56577Sbostic default : 66*56577Sbostic response->answer = UNKNOWN_REQUEST; 67*56577Sbostic break; 68*56577Sbostic } 69*56577Sbostic } 70*56577Sbostic 71*56577Sbostic struct hostent *gethostbyaddr(); 72*56577Sbostic 73*56577Sbostic do_announce(request, response) 74*56577Sbostic CTL_MSG *request; 75*56577Sbostic CTL_RESPONSE *response; 76*56577Sbostic { 77*56577Sbostic struct hostent *hp; 78*56577Sbostic CTL_MSG *ptr; 79*56577Sbostic int result; 80*56577Sbostic 81*56577Sbostic /* see if the user is logged */ 82*56577Sbostic result = find_user(request->r_name, request->r_tty); 83*56577Sbostic if (result != SUCCESS) { 84*56577Sbostic response->answer = result; 85*56577Sbostic return; 86*56577Sbostic } 87*56577Sbostic hp = gethostbyaddr(&request->ctl_addr.sin_addr, 88*56577Sbostic sizeof(struct in_addr), AF_INET); 89*56577Sbostic if (hp == (struct hostent *)0) { 90*56577Sbostic response->answer = MACHINE_UNKNOWN; 91*56577Sbostic return; 92*56577Sbostic } 93*56577Sbostic ptr = find_request(request); 94*56577Sbostic if (ptr == (CTL_MSG *) 0) { 95*56577Sbostic insert_table(request,response); 96*56577Sbostic response->answer = announce(request, hp->h_name); 97*56577Sbostic return; 98*56577Sbostic } 99*56577Sbostic if (request->id_num > ptr->id_num) { 100*56577Sbostic /* 101*56577Sbostic * this is an explicit re-announce, so update the id_num 102*56577Sbostic * field to avoid duplicates and re-announce the talk 103*56577Sbostic */ 104*56577Sbostic ptr->id_num = response->id_num = new_id(); 105*56577Sbostic response->answer = announce(request, hp->h_name); 106*56577Sbostic return; 107*56577Sbostic } 108*56577Sbostic /* a duplicated request, so ignore it */ 109*56577Sbostic response->id_num = ptr->id_num; 110*56577Sbostic response->answer = SUCCESS; 111*56577Sbostic } 112*56577Sbostic 113*56577Sbostic #include <utmp.h> 114*56577Sbostic 115*56577Sbostic /* 116*56577Sbostic * Search utmp for the local user 117*56577Sbostic */ 118*56577Sbostic find_user(name, tty) 119*56577Sbostic char *name; 120*56577Sbostic char *tty; 121*56577Sbostic { 122*56577Sbostic struct utmp ubuf; 123*56577Sbostic int status; 124*56577Sbostic FILE *fd; 125*56577Sbostic struct stat statb; 126*56577Sbostic char ftty[20]; 127*56577Sbostic 128*56577Sbostic if ((fd = fopen("/etc/utmp", "r")) == NULL) { 129*56577Sbostic perror("Can't open /etc/utmp"); 130*56577Sbostic return (FAILED); 131*56577Sbostic } 132*56577Sbostic #define SCMPN(a, b) strncmp(a, b, sizeof (a)) 133*56577Sbostic status = NOT_HERE; 134*56577Sbostic (void) strcpy(ftty, "/dev/"); 135*56577Sbostic while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1) 136*56577Sbostic if (SCMPN(ubuf.ut_name, name) == 0) { 137*56577Sbostic if (*tty == '\0') { 138*56577Sbostic status = PERMISSION_DENIED; 139*56577Sbostic /* no particular tty was requested */ 140*56577Sbostic (void) strcpy(ftty+5, ubuf.ut_line); 141*56577Sbostic if (stat(ftty,&statb) == 0) { 142*56577Sbostic if (!(statb.st_mode & 020)) 143*56577Sbostic continue; 144*56577Sbostic (void) strcpy(tty, ubuf.ut_line); 145*56577Sbostic status = SUCCESS; 146*56577Sbostic break; 147*56577Sbostic } 148*56577Sbostic } 149*56577Sbostic if (strcmp(ubuf.ut_line, tty) == 0) { 150*56577Sbostic status = SUCCESS; 151*56577Sbostic break; 152*56577Sbostic } 153*56577Sbostic } 154*56577Sbostic fclose(fd); 155*56577Sbostic return (status); 156*56577Sbostic } 157