/* * SMAILCHK.C * * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved * * Check the mailbox and reports if new mail * has arrived. Connects to the Mailchk client on the Amiga. * Accepts only one connection. * * Written by S. Laroche. */ #include #include #include #include #include #include #include #include "servers.h" #define BUFLENGTH 512 extern int errno; void do_mailchk(); char delmailmsg(); char copyfiles(); long numsecs; char firstrun; int fd; main(ac,av) char *av[]; { long chann = DListen(PORT_MAILCHK); char result; if (av[1]) chdir(av[1]); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, do_mailchk); for (;;) { fd = DAccept(chann); if (fd < 0) { if (errno == EINTR) continue; break; } getmailpath(); while (ggread(fd,&result,1) == 1) { Whatdoyouwant(fd,result); } close(fd); _exit(1); } perror("SMAILCHK"); } char buf[256], mname[256]; getmailpath() { char *buffer; buffer = (char *) getenv("MAIL"); if (buffer == NULL) { strcpy(mname,"/var/spool/mail/"); } else { strcpy(mname,buffer); strcat(mname,"/"); } cuserid(buf); strcat(mname,buf); } Whatdoyouwant(fd,result) int fd; char result; /* This function interprets requests from the Amiga client. 0 -> Do nothing 1 -> Send the mail header from Mail. 2 -> Send a particular message. 3 -> Delete a particular message. 4 -> Initial handshake */ { char dummy, *buffer; FILE *fi; switch(result) { case 1 : fi = popen("mail -H","r"); if (fi == NULL) { perror("SMAILCHK, mail program not found"); exit(0); } while (fgets(buf,256,fi) != NULL) { dummy = strlen(buf); buf[dummy-1] = 0; gwrite(fd,&dummy,1); gwrite(fd,buf,dummy); } dummy = 0; gwrite(fd,&dummy,1); if (ferror(fi)) { perror("SMAILCHK, error executing mail"); exit(0); } pclose(fi); break; case 2 : buffer = (char *) malloc(BUFLENGTH); if (buffer == NULL) { fprintf(stderr,"SMAILCHK: not enough memory\n"); } else { sendmailmsg(fd,mname,buffer); free(buffer); } break; case 3 : { char ok; ok = delmailmsg(fd,mname); gwrite(fd,&ok,1); if (ok) { alarm(0); do_mailchk();} } break; case 4 : if ((ggread(fd,&numsecs,4) == 4) && (ggread(fd,&firstrun,1) == 1)) { alarm(0); do_mailchk(); } else { close(fd); _exit(1); } } } void do_mailchk() { char dummy, *s_mtime; struct stat tempbuf; static char nomail = 1; static long lasttime = 0; strcpy(buf,"="); alarm(numsecs); if (stat(mname,&tempbuf) == -1) { if (errno == ENOENT) { if (nomail) { strcpy(buf,"No mail."); nomail = 0; } } else perror("SMAILCHK, Unable to examine file"); } else { if (tempbuf.st_mtime >= tempbuf.st_atime) { s_mtime = ctime(&tempbuf.st_mtime); strcpy(buf,"New mail arrived on "); strcat(buf,s_mtime); nomail = 1; } else if ((firstrun && (tempbuf.st_mtime > lasttime)) || firstrun == 2) strcpy(buf,"You have mail\n"); lasttime = tempbuf.st_mtime; } dummy = strlen(buf); if (dummy > 2) { gwrite(fd, &dummy, 1); gwrite(fd, buf, dummy); } firstrun = 1; } sendmailmsg(fd,mname,buffer) char *buffer, *mname; int fd; { int len= BUFLENGTH; long nochars, stchar; char dummy; FILE *fi; if (ggread(fd,&stchar,4) == 4) { if (ggread(fd,&nochars,4) == 4) { if (fi = fopen(mname,"r")) { if (fseek(fi,stchar,0) < 0) { fclose(fi); exit; } else { dummy = 0; while (nochars > len) { fread(buffer,1,len,fi); nochars -= len; gwrite(fd,&len,4); gwrite(fd,buffer,len); ggread(fd,&dummy,1); if (dummy) break; } if (dummy == 0) { if (fread(buffer,1,nochars,fi) != nochars) { perror("SMAILCHK, unable to read mail file"); exit; } gwrite(fd,&nochars,4); gwrite(fd,buffer,nochars); ggread(fd,&dummy,1); nochars = 0; gwrite(fd,&nochars,4); } } fclose(fi); } } } } char delmailmsg(fd,mname) char *mname; int fd; { long nochars, stchar; FILE *f1, *f2; char ok = 0, *tname; if (!(tname = (char *) getenv("DNETDIR"))) return(ok); strcpy(buf,tname); strcat(buf,"MAIL0001"); if (ggread(fd,&stchar,4) == 4) if (ggread(fd,&nochars,4) == 4) if ((f1 = fopen(mname,"r")) && (f2 = fopen(buf,"w+"))) { if (copyfiles(f1,f2,stchar)) if (fseek(f1,nochars,1) == 0) if (ok = copyfiles(f1,f2,-1)) { fclose(f1); if (unlink(mname) < 0) { perror("SMAILCHK, Error while removing"); fclose(f2); unlink(buf); return(0); } rewind(f2); if (f1 = fopen(mname,"w")) { fchmod(f1,0600); ok = copyfiles(f2,f1,-1); fclose(f1); fclose(f2); unlink(buf); } else { perror("SMAILCHK, Error writing in spool dir"); fclose(f2); return(0); } if (f1 = fopen(mname,"r")) { /* Touch the file */ char f = 0; fseek(f1,0,2); if (ftell(f1) < 2) f = 1; fclose(f1); if (f) unlink(mname); } return(ok); } perror("SMAILCHK, Error while writing"); fclose(f1); fclose(f2); return(0); } perror("SMAILCHK, Delete operation"); return(0); } char copyfiles(f1,f2,n) FILE *f1, *f2; long n; { char buffer[1024], ok = 1; int tmp; while (n > 1024 || n < 0) { if (n > 0) n -= 1024; if ((tmp = fread(buffer,1,1024,f1)) == 1024) if (fwrite(buffer,1,1024,f2) == 1024) continue; ok = 0; break; } while (ok && n > 0) { if (fread(buffer,1,n,f1) == n) if (fwrite(buffer,1,n,f2) == n) break; ok = 0; } if (n >= 0) return(ok); if (fwrite(buffer,1,tmp,f2) == tmp) ok = 1; return(ok); }