⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 操作系统源代码
💻 C
字号:
/* process.c Copyright Michael Temari 07/22/1996 All Rights Reserved */#include <sys/types.h>#include <sys/stat.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <ctype.h>#include <time.h>#include <net/hton.h>#include <net/gen/socket.h>#include <net/gen/in.h>#include <net/gen/netdb.h>#include "talk.h"#include "talkd.h"#include "process.h"#include "finduser.h"struct entry {	struct entry *prev;	struct talk_request rq;	time_t expire;	struct entry *next;};_PROTOTYPE(static int announce, (struct talk_request *request, char *rhost));_PROTOTYPE(static struct talk_request *lookup, (struct talk_request *request, int type));_PROTOTYPE(static int addreq, (struct talk_request *request));_PROTOTYPE(static delete_invite, (long id));_PROTOTYPE(static long nextid, (void));_PROTOTYPE(static void delete, (struct entry *e));static struct entry *entry = (struct entry *)NULL;int processrequest(request, reply)struct talk_request *request;struct talk_reply *reply;{char *p;struct talk_request *rq;struct hostent *hp;   reply->version = TALK_VERSION;   reply->type = request->type;   reply->answer = 0;   reply->junk = 0;   reply->id = htonl(0);   /* check version */   if(request->version != TALK_VERSION) {   	reply->answer = BADVERSION;   	return(0);   }   /* check address family */   if(ntohs(request->addr.sa_family) != AF_INET) {   	reply->answer = BADADDR;   	return(0);   }   /* check control address family */   if(ntohs(request->ctl_addr.sa_family) != AF_INET) {   	reply->answer = BADCTLADDR;   	return(0);   }   /* check local name */   p = request->luser;   while(*p)   	if(!isprint(*p)) {   		reply->answer = FAILED;   		return(0);   	} else   		p++;   switch(request->type) {   	case ANNOUNCE:		reply->answer = find_user(request->ruser, request->rtty);		if(reply->answer != SUCCESS) break;		hp = gethostbyaddr((char *)&request->ctl_addr.sin_addr, sizeof(ipaddr_t), AF_INET);		if(hp == (struct hostent *)NULL) {			reply->answer = MACHINE_UNKNOWN;			break;		}		if((rq = lookup(request, 1)) == (struct talk_request *)NULL) {			reply->id = addreq(request);			reply->answer = announce(request, hp->h_name);			break;		}		if(ntohl(request->id) > ntohl(rq->id)) {			rq->id = nextid();			reply->id = rq->id;			reply->answer = announce(request, hp->h_name);		} else {			reply->id = rq->id;			reply->answer = SUCCESS;		}   		break;   	case LEAVE_INVITE:		rq = lookup(request, 1);		if(rq == (struct talk_request *)NULL)			reply->id = addreq(request);		else {			reply->id = rq->id;			reply->answer = SUCCESS;		}   		break;   	case LOOK_UP:		if((rq = lookup(request, 0)) == (struct talk_request *)NULL)			reply->answer = NOT_HERE;		else {			reply->id = rq->id;			memcpy((char *)&reply->addr, (char *)&rq->addr, sizeof(reply->addr));			reply->answer = SUCCESS;		}   		break;   	case DELETE:		reply->answer = delete_invite(request->id);   		break;   	default:   		reply->answer = UNKNOWN_REQUEST;   }   return(0);}static int announce(request, rhost)struct talk_request *request;char *rhost;{char tty[5+TTY_SIZE+1];struct stat st;FILE *fp;time_t now;struct tm *tm;   sprintf(tty, "/dev/%s", request->rtty);   if(stat(tty, &st) < 0)   	return(PERMISSION_DENIED);   if(!(st.st_mode & S_IWGRP))   	return(PERMISSION_DENIED);   if((fp = fopen(tty, "w")) == (FILE *)NULL)   	return(PERMISSION_DENIED);   (void) time(&now);   tm = localtime(&now);   fprintf(fp, "\007\007\007\rtalkd: Message from talkd@%s at %d:%02d:%02d\r\n",		myhostname, tm->tm_hour, tm->tm_min, tm->tm_sec);   fprintf(fp, "talkd: %s@%s would like to talk to you\r\n",   		request->luser, rhost);   fprintf(fp, "talkd: to answer type:  talk %s@%s\r\n",   		request->luser, rhost);   fclose(fp);   return(SUCCESS);}static struct talk_request *lookup(request, type)struct talk_request *request;int type;{time_t now;struct entry *e;   (void) time(&now);   for(e = entry; e != (struct entry *)NULL; e = e->next) {	if(now > e->expire) {		delete(e);		continue;	}	if(type == 0) {		if(!strncmp(request->luser, e->rq.ruser, USER_SIZE) &&		   !strncmp(request->ruser, e->rq.luser, USER_SIZE) &&		   e->rq.type == LEAVE_INVITE)			return(&e->rq);	} else {		if(request->type == e->rq.type &&	  	   request->pid == e->rq.pid &&		   !strncmp(request->luser, e->rq.luser, USER_SIZE) &&		   !strncmp(request->ruser, e->rq.ruser, USER_SIZE)) {			e->expire = now + MAX_LIFE;			return(&e->rq);		}	}   }   return((struct talk_request *)NULL);}static int addreq(request)struct talk_request *request;{time_t now;struct entry *e;   (void) time(&now);   request->id = nextid();   e = (struct entry *) malloc(sizeof(struct entry));   if(e == (struct entry *)NULL) {   	fprintf(stderr, "talkd: out of memory in insert table\n");   	exit(1);   }   e->expire = now + MAX_LIFE;   memcpy((char *)&e->rq, (char *)request, sizeof(struct talk_request));   e->next = entry;   if(e->next != (struct entry *)NULL)   	e->next->prev = e;   e->prev = (struct entry *)NULL;   entry = e;   return(request->id);}static int delete_invite(id)long id;{time_t now;struct entry *e;   (void) time(&now);   for(e = entry; e != (struct entry *)NULL; e = e->next) {	if(now > e->expire) {		delete(e);		continue;	}	if(e->rq.id == id) {		delete(e);		return(SUCCESS);	}   }   return(NOT_HERE);}static void delete(e)struct entry *e;{   if(e == (struct entry *)NULL) return;   if(entry == e)	entry = e->next;   else	if(e->prev != (struct entry *)NULL)		e->prev->next = e->next;   if(e->next != (struct entry *)NULL)	e->next->prev = e->prev;   free((char *)e);   return;}static long nextid(){static long id = 0;   id++;   if(id <= 0) id = 1;   return(htonl(id));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -