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

📄 mailbox.c

📁 TCP_IPprotocol.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
		len = MAXSOCKSIZE;
		i = getpeername(fileno(m->user),&dsocket,&len);
		sprintf(m->startmsg,"*** Incoming call from %s@%s ***\n",
			m->name,i != -1 ? psocket(&dsocket): Hostname);
	}
	return gw_connect(m,s,(struct sockaddr *)&fsocket,SOCKSIZE);
}

static int
dombfinger(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct mbx *m;
	char *host, *user = NULL, buf[8], *newargv[3];

	if(argc > 2){
		printf("Usage: F user@host  or  F @host  or  F user.\n");
		return 0;
	}
	host = Hostname;
	if(argc == 2){
		if((host = strchr(argv[1], '@')) != NULL){
			*host = '\0';
			host++;
		} else
			host = Hostname;
		user = argv[1];
	}
	m = (struct mbx *) p;
	m->startmsg = mallocw(80);
	if(user != NULL)
		sprintf(m->startmsg,"%s\n",user);
	else
		strcpy(m->startmsg,"\n");
	newargv[0] = "telnet";
	newargv[1] = host;
	sprintf(buf,"%d",IPPORT_FINGER);
	newargv[2] = buf;
	return dombtelnet(3,newargv,p);
}

/* Generic mbox gateway code. It sends and frees the contents of m->startmsg
 * when the connection has been established unless it a null pointer.
 */
int
gw_connect(m,s,fsocket,len)
struct mbx *m;
int s;
struct sockaddr *fsocket;
int len;
{
	int c;
	char *cp;
	struct proc *child;
	struct gwalarm *gwa;
	FILE *network;

	child = newproc("gateway supervisor",256,gw_superv,0,Curproc,m,0);
	printf("Trying %s...  ",psocket(fsocket));
	dombescape(0,NULL,(void *)m);
	fflush(stdout);
	if(connect(s,fsocket,len) == -1){
		cp = sockerr(s);
		printf("Connection failed: ");
		if(cp != NULL)
			printf("%s errno %d\n",cp,errno);
		else
			printf("Escape character sent.\n");
		free(m->startmsg);
		m->startmsg = NULL;
		killproc(child);
		close_s(s);
		return 0;
	}
	network = fdopen(s,"r+t");
	/* The user did not type the escape character */
	killproc(child);
	puts("Connected.");
	
	if(m->startmsg != NULL){
		fputs(m->startmsg,network);
		free(m->startmsg);
		m->startmsg = NULL;
	}
	/* Since NOS does not flush the output socket after a certain
	 * period of time, we have to arrange that ourselves.
	 */
	gwa = (struct gwalarm *) mallocw(sizeof(struct gwalarm));
	gwa->s1 = stdout;
	gwa->s2 = network;
	set_timer(&gwa->t,240L);
	gwa->t.func = gw_alarm;
	gwa->t.arg = (void *) gwa;
	start_timer(&gwa->t);
	/* Fork off the receive process */
	child = newproc("gateway in",1024,gw_input,s,(void *)network,Curproc,0);
	
	for(;;){
		if((c = getchar()) == EOF)
			break;
		if(c == m->escape){
			puts("Disconnecting.");
			if(socklen(fileno(stdin),0))
				recv_mbuf(fileno(stdin),NULL,0,NULL,0);
			break;
		}
		if(putc(c,network) == EOF)
			break;
	}
	stop_timer(&gwa->t);
	free(gwa);
	fclose(network);
	killproc(child); /* get rid of the receive process */
	printf("%c%c%c\n",IAC,WONT,TN_ECHO);
	return 0;
}

static void
gw_input(s,n,p)
int s;
void *n;
void *p;
{
	int c;
	char *cp;
	struct proc *parent;
	FILE *network;

	network = (FILE *)n;
	parent = (struct proc *) p;
	while((c = getc(network)) != EOF)
		putchar((char)c);
	printf("Disconnected ");
	cp = sockerr(fileno(network));
	if(cp != NULL)
		puts(cp);
	/* Tell the parent that we are no longer connected */
	alert(parent,ENOTCONN);
	kwait(Curproc); /* Now wait to be killed */
}

/* Check if the escape character is typed while the parent process is busy
 * doing other things. 
 */
static void
gw_superv(null,proc,p)
int null;
void *proc;
void *p;
{
	struct proc *parent;
	struct mbx *m;
	int c;
	parent = (struct proc *) proc;
	m = (struct mbx *) p;
	while((c = getchar()) != EOF)
		if(c == m->escape){
			/* flush anything in the input queue */
			if(socklen(fileno(stdin),0))
				recv_mbuf(fileno(stdin),NULL,0,NULL,0);
			break;
		}
	alert(parent,EINTR);	 /* Tell the parent to quit */
	kwait(Curproc);		 /* Please kill me */
}

static void
gw_alarm(p)
void *p;
{
	struct gwalarm *gwa = (struct gwalarm *)p;
	char oldbl;
	struct usock *up;

	/* Flush sockets s1 and s2, but first make sure that the socket
	 * is set to non-blocking mode, to prevent the flush from blocking
	 * if the high water mark has been reached.
	 */
	if((up = itop(fileno(gwa->s1))) != NULL) {
		oldbl = up->noblock;
		up->noblock = 1;
		fflush(gwa->s1);
		up->noblock = oldbl;
	}
	if((up = itop(fileno(gwa->s2))) != NULL) {
		oldbl = up->noblock;
		up->noblock = 1;
		fflush(gwa->s2);
		up->noblock = oldbl;
	}
	start_timer(&gwa->t);
}

/* States for send line parser state machine */
#define		LOOK_FOR_USER		2
#define		IN_USER			3
#define		AFTER_USER		4
#define		LOOK_FOR_HOST		5
#define		IN_HOST			6
#define		AFTER_HOST		7
#define		LOOK_FOR_FROM		8
#define		IN_FROM			9
#define		AFTER_FROM		10
#define		LOOK_FOR_MSGID		11
#define		IN_MSGID		12
#define		FINAL_STATE		13
#define		ERROR_STATE		14

/* Prepare the addressee.  If the address is bad, return -1, otherwise
 * return 0
 */
static int
mbx_to(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	register char *cp;
	int state, i;
	char *user, *host, *from, *msgid;
	int userlen = 0, hostlen = 0, fromlen = 0, msgidlen = 0;
	struct mbx *m;

	m = (struct mbx *)p;
	/* Free anything that might be allocated
	 * since the last call to mbx_to() or mbx_reply()
	 */
	free(m->to);
	m->to = NULL;
	free(m->tofrom);
	m->tofrom = NULL;
	free(m->tomsgid);
	m->tomsgid = NULL;
	free(m->origto);
	m->origto = NULL;

	if(argc == 1)
		return -1;
	i = 1;
	cp = argv[i];
	state = LOOK_FOR_USER;
	while(state < FINAL_STATE){
#ifdef MBDEBUG
		printf("State is %d, char is %c\n", state, *cp);
#endif
		switch(state){
		case LOOK_FOR_USER:
			if(*cp == '@' || *cp == '<' || *cp == '$'){
				state = ERROR_STATE;		/* no user */
			} else {
				user = cp;			/* point at start */
				userlen++;			/* start counting */
				state = IN_USER;
			}
			break;
		case IN_USER:
			switch(*cp){
			case '\0':
				state = AFTER_USER;		/* done with username */
				break;
			case '@':
				state = LOOK_FOR_HOST;		/* hostname should follow */
				break;
			case '<':
				state = LOOK_FOR_FROM;		/* from name should follow */
				break;
			case '$':
				state = LOOK_FOR_MSGID;	/* message id should follow */
				break;
			default:
				userlen++;			/* part of username */
			}
			break;
		case AFTER_USER:
			switch(*cp){
			case '@':
				state = LOOK_FOR_HOST;		/* hostname follows */
				break;
			case '<':
				state = LOOK_FOR_FROM;		/* fromname follows */
				break;
			case '$':
			state = LOOK_FOR_MSGID;	/* message id follows */
				break;
			default:
				state = ERROR_STATE;
			}
			break;
		case LOOK_FOR_HOST:
			if(*cp == '@' || *cp == '<' || *cp == '$'){
				state = ERROR_STATE;
				break;
			}
			if(*cp == '\0')
				break;
			host = cp;
			hostlen++;
			state = IN_HOST;
			break;
		case IN_HOST:
			switch(*cp){
			case '\0':
				state = AFTER_HOST;		/* found user@host */
				break;
			case '@':
				state = ERROR_STATE;		/* user@host@? */
				break;
			case '<':
				state = LOOK_FOR_FROM;		/* fromname follows */
				break;
			case '$':
				state = LOOK_FOR_MSGID;	/* message id follows */
				break;
			default:
				hostlen++;
			}
			break;
		case AFTER_HOST:
			switch(*cp){
			case '@':
				state = ERROR_STATE;		/* user@host @ */
				break;
			case '<':
				state = LOOK_FOR_FROM;		/* user@host < */
				break;
			case '$':
				state = LOOK_FOR_MSGID;	/* user@host $ */
				break;
			default:
				state = ERROR_STATE;		/* user@host foo */
			}
			break;
		case LOOK_FOR_FROM:
			if(*cp == '@' || *cp == '<' || *cp == '$'){
				state = ERROR_STATE;
				break;
			}
			if(*cp == '\0')
				break;
			from = cp;
			fromlen++;
			state = IN_FROM;
			break;
		case IN_FROM:
			switch(*cp){
			case '\0':
				state = AFTER_FROM;		/* user@host <foo */
				break;
			case '<':
				state = ERROR_STATE;		/* user@host <foo< */
				break;
			case '$':
				state = LOOK_FOR_MSGID;	/* message id follows */
				break;
			default:
				fromlen++;
			}
			break;
		case AFTER_FROM:
			switch(*cp){
			case '@':				/* user@host <foo @ */
			case '<':				/* user@host <foo < */
				state = ERROR_STATE;
				break;
			case '$':
				state = LOOK_FOR_MSGID;	/* user@host <foo $ */
				break;
			default:
				state = ERROR_STATE;		/* user@host foo */
			}
			break;
		case LOOK_FOR_MSGID:
			if(*cp == '\0')
				break;
			msgid = cp;
			msgidlen++;
			state = IN_MSGID;
			break;
		case IN_MSGID:
			if(*cp == '\0')
				state = FINAL_STATE;
			else
				msgidlen++;
			break;
		default:
			/* what are we doing in this state? */
			state = ERROR_STATE;
		}
		if(*(cp) == '\0'){
			++i;
			if(i < argc)
			cp = argv[i];
			else break;
		} else
			++cp;
	}
	if(state == ERROR_STATE || state == LOOK_FOR_HOST
	 || state == LOOK_FOR_FROM || state == LOOK_FOR_MSGID)
		return -1;		/* syntax error */

	m->to = mallocw(userlen + hostlen + 2);

	strncpy(m->to, user, userlen);
	m->to[userlen] = '\0';

	if(hostlen){
		m->to[userlen] = '@';
		strncpy(m->to + userlen + 1, host, hostlen);
		m->to[userlen + hostlen + 1] = '\0';
	}
	if(fromlen){
		m->tofrom = mallocw(fromlen + 1);
		strncpy(m->tofrom, from, fromlen);
		m->tofrom[fromlen] = '\0';
	}
	if(msgidlen){
		m->tomsgid = mallocw(msgidlen + 1);
		strncpy(m->tomsgid, msgid, msgidlen);
		m->tomsgid[msgidlen] = '\0';
	}
	return 0;
}

/* This opens the data file and writes the mail header into it.
 * Returns 0 if OK, and -1 if not.
 */
static int
mbx_data(m,cclist,extra)
struct mbx *m;
struct list *cclist;	/* list of carbon copy recipients */
char *extra;		/* optional extra header lines */
{
	time_t t;
	struct list *ap;
	int cccnt = 0;
	
	if((m->tfile = tmpfile()) == NULL)
		return -1;
	time(&t);
	fprintf(m->tfile,Hdrs[RECEIVED]);
	if(m->tofrom != NULL)
		fprintf(m->tfile,"from %s.bbs ",m->name);
	fprintf(m->tfile,"by %s (%s)\n\tid AA%ld ; %s",
		Hostname, Version, get_msgid(), ptime(&t));
	fprintf(m->tfile,"%s%s",Hdrs[DATE],ptime(&t));
	fprintf(m->tfile,Hdrs[MSGID]);
	if(m->tomsgid)
		fprintf(m->tfile,"<%s@%s.bbs>\n", m->tomsgid, m->name);
	else
		fprintf(m->tfile,"<%ld@%s>\n",get_msgid(), Hostname);
	fprintf(m->tfile,Hdrs[FROM]);
	if(m->tofrom)
		fprintf(m->tfile,"%s%%%s.bbs@%s\n",
			m->tofrom, m->name, Hostname);
	else
		fprintf(m->tfile,"%s@%s\n", m->name, Hostname);
	fprintf(m->tfile,"%s%s\n",Hdrs[TO],m->origto != NULL ? m->origto : m->to);
	/* Write Cc: line */
	for(ap = cclist; ap != NULL; ap = ap->next) {
		if(cccnt == 0){
			fprintf(m->tfile,"%s",Hdrs[CC]);
			cccnt = 4;
		}
		else {
		       fprintf(m->tfile,", ");
		       cccnt += 2;
		}
		if(cccnt + strlen(ap->val) > 80 - 3) {
		       fprintf(m->tfile,"\n    ");
		       cccnt = 4;
		}
		fputs(ap->val,m->tfile);
		cccnt += strlen(ap->val);
	}
	if(cccnt)
		fputc('\n',m->tfile);
	fprintf(m->tfile,"%s%s\n",Hdrs[SUBJECT],m->line);
	if(!isspace(m->stype) && ((m->stype != 'R' && m->stype != 'F') ||
	  (m->sid & MBX_SID) !=0))
		  fprintf(m->tfile,"%s%c\n", Hdrs[BBSTYPE],m->stype);
	if(extra != NULL)
		fprintf(m->tfile,extra);
	fprintf(m->tfile,"\n");

	return 0;
}

/* Returns true if string is in history file or if string appears to be a
 * message id generated by our system.
 */
static int
msgidcheck(string)
char *string;
{
     FILE *fp;
     char buf[LINELEN], *cp;
     if(string == NULL)
	  return 0;
     /* BID's that we have generated ourselves are not kept in the history
      * file. Such BID's are in the nnnn_hhhh form, where hhhh is a part of
      * our hostname, truncated so that the BID is no longer than 11
      * characters.
      */
     if((cp = strchr(string,'_')) != NULL && *(cp+1) != '\0' && 
	strnicmp(cp+1,Hostname,strlen(cp+1)) == 0)
	  return 1;

     if((fp = fopen(Historyfile,READ_TEXT)) == NULL)
	  return 0;
     while(fgets(buf,LINELEN,fp) != NULL) {
	  rip(buf);
	  if(stricmp(string,buf) == 0) {	/* found */
	       fclose(fp);
	       return 1;
	  }
     }
     fclose(fp);
     return 0;
}
     

/* uuencode a file -- translated from C++; both versions copyright 1990
   by David R. Evans, G4AMJ/NQ0I
*/

static int
uuencode(infile,outfile,infilename)
FILE *infile;
FILE *outfile;
char *infilename;
{
  int n_read_so_far = 0, n_written_so_far = 0, in_chars, n, mode = 0755;
  int32 cnt = 0;
  unsigned char in[3], out[4], line[100];
#ifdef UNIX
  struct stat stb;
  
  if(stat(infilename,&stb) != -1)
       mode = stb.st_mode & 0777;	/* get real file protection mode */
#endif
  fprintf(outfile, "begin %03o %s\n", mode, infilename);

  /* do the encode */
  for(;;) {
    in_chars = fread(in, 1, 3, infile);
    out[0] = in[0] >> 2;
    out[1] = in[0] << 6;
    out[1] = out[1] >> 2;
    out[1] = out[1] | (in[1] >> 4);
    out[2] = in[1] << 4;
    out[2] = out[2] >> 2;
    out[2] = out[2] | (in[2] >> 6);
    out[3] = in[2] << 2;
    out[3] = out[3] >> 2;
    for (n = 0; n < 4; n++)
      out[n] += ' ';
    n_read_so_far += in_chars;
    for (n = 0; n < 4; n++)
      line[n_written_so_far++] = out[n];
    if (((in_chars != 3) || (n_written_so_far == 60)) && n_read_so_far > 0) {
      line[(n_read_so_far + 2) / 3 * 4] = '\0';
      
      fprintf(outfile,"%c%s\n",n_read_so_far + ' ', line);
      cnt += n_read_so_far;
      n_read_so_far = 0;
      n_written_so_far = 0;
    }
    if (in_chars == 0)
      break;
  }
  if (fprintf(outfile," \nend\nsize %lu\n", cnt) == EOF)
    return 1;
  return 0;
}

⌨️ 快捷键说明

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