Path: wuarchive!texbell!texsun!newstop!sun-barr!lll-winken!xanth!cs.odu.edu!Amiga-Request
From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
Newsgroups: comp.sources.amiga
Subject: v90i157: mailchk 03 - mail client+server for DNet, Part01/02
Message-ID: <12326@xanth.cs.odu.edu>
Date: 26 Apr 90 01:46:57 GMT
Sender: news@cs.odu.edu
Reply-To: <lobster@quiche.cs.mcgill.ca>
Lines: 2254
Approved: tadguy@cs.odu.edu (Tad Guy)
X-Mail-Submissions-To: Amiga@cs.odu.edu
X-Post-Discussions-To: comp.sys.amiga

Submitted-by: <lobster@quiche.cs.mcgill.ca>
Posting-number: Volume 90, Issue 157
Archive-name: comm/dnet/mailchk-03/part01

[ uuencoded executable enclosed  ...tad ]

Mailchk is a mail client/server for Dnet.  This new version features
limited speech capabilities and a reply facility.  Note that Mailchk
no longer requires the Unix Mail program.

Stephane Laroche
lobster@calvin.cs.mcgill.ca

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  amiga amiga/bin amiga/client amiga/client/DMakefile
#   amiga/client/mailchk.c amiga/client/mailmenu.h amiga/doc
#   amiga/doc/mailchk.doc amiga/server amiga/server/servers.h
#   amiga/version.h unix unix/README.SMAILCHK unix/doc
#   unix/doc/smailchk.doc unix/lib unix/lib/Makefile
#   unix/lib/dnetlib.c unix/lib/dnetlib.h unix/server
#   unix/server/Makefile unix/server/servers.h unix/server/smailchk.c
# Wrapped by tadguy@xanth on Wed Apr 25 21:46:33 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'amiga' ; then
    echo shar: Creating directory \"'amiga'\"
    mkdir 'amiga'
fi
if test ! -d 'amiga/bin' ; then
    echo shar: Creating directory \"'amiga/bin'\"
    mkdir 'amiga/bin'
fi
if test ! -d 'amiga/client' ; then
    echo shar: Creating directory \"'amiga/client'\"
    mkdir 'amiga/client'
fi
if test -f 'amiga/client/DMakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/client/DMakefile'\"
else
echo shar: Extracting \"'amiga/client/DMakefile'\" \(632 characters\)
sed "s/^X//" >'amiga/client/DMakefile' <<'END_OF_FILE'
X
X#	DNET CLIENTS
X#
X#  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
X#
X#   Aztec C Compilation and Makefile
X
XLFLAGS	= +Q
XSYMS	= include:symbols.m
XSYMD	= ram:symbols.m
XCFLAGS	= +L +I$(SYMS)
XBIN	= /bin/
XOBDIR	= tmp:dnet/
XSRCS	= *.c
XOBJS	= $(OBDIR)*.o
X
Xall: $(SYMS) /lib/dnetlib.lib $(BIN)*
X
X$(BIN)* : $(OBJS)
X	ln $(LFLAGS) %(right) -l/lib/dnetlib -la -lsup32 -lc32 -o %(left)
X
X
X$(OBJS): $(SRCS)
X	cc $(CFLAGS) %(right) -o t:dnet_temp.o
X	copy T:dnet_temp.o %(left)
X	-delete t:dnet_temp.o
X
X/lib/dnetlib.lib: /lib/dnetlib.c
X	cd /lib
X	dmake
X	cd /client
X
Xclean:
X	-delete $(OBDIR)#?.o
X
X$(SYMD) : $(SYMS)
X	Copy %(right) %(left)
X
END_OF_FILE
if test 632 -ne `wc -c <'amiga/client/DMakefile'`; then
    echo shar: \"'amiga/client/DMakefile'\" unpacked with wrong size!
fi
# end of 'amiga/client/DMakefile'
fi
if test -f 'amiga/client/mailchk.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/client/mailchk.c'\"
else
echo shar: Extracting \"'amiga/client/mailchk.c'\" \(18325 characters\)
sed "s/^X//" >'amiga/client/mailchk.c' <<'END_OF_FILE'
X
X/*
X *	MAILCHK.C
X *
X *	DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
X *
X *	Check the mailbox and reports if new mail
X *	has arrived.
X *
X *	Written by S. Laroche.
X *
X *	Usage:	mailchk -N(host) -q -d -t(time)
X *		-d:  Display old mail on startup, if it exists
X *		-q:  Quiet, don't display old mail on startup
X *		Default:  -d
X *
X *		-t:  (time) is the number of seconds between checks.
X *		Default:  40 seconds
X *
X *		-h:  help message
X *
X *	Arp.library is needed... (Version 39.1)
X */
X
X#include <stdio.h>
X#include <local/typedefs.h>
X#include <libraries/arpbase.h>
X#include "/dnet/channel.h"
X#include "/server/servers.h"
X#include <local/deemu.h>
X#include "mailmenu.h"
X
Xshort Deemu[] = {
X    DMSTRT, 0, 0,
X    DMNW  , 0, 10, 2, 2, -80, 40, 0xFFFF,
X    DMEND , 0, 0
X};
X
X#define DMNWOFF 4
X
X#define NA	     0
X#define MAILLENGTH 256
X#define BUFLENGTH  512
X#define MENUSTRIP(n) (SHIFTMENU(n)|SHIFTITEM(NOITEM))
Xubyte Title[128];
X
XNW Nw = {
X    0, 0, 320, 50, -1, -1,
X    NEWSIZE|MENUPICK|CLOSEWINDOW|MOUSEBUTTONS,
X    WINSTD|NOCAREREFRESH,
X    NULL, NULL, Title, NULL, NULL,
X    32, 18, -1, -1, WBENCHSCREEN
X};
X
Xstruct MailMsg {
X  char msg[MAILLENGTH];
X  struct MailMsg *next;
X};
X
Xstruct mailmsg {
X  struct Message ml_msg;
X  unsigned long secs;
X  BYTE quit, speak, win;
X};
X
Xstruct MailMsg *MailP=NULL;
X
XWIN *Win = NULL;
XRP  *Rp;
X
Xchar DefaultSpeaker[] = "SPEAK:";
X
X/* int Enable_Abort; */
X
Xlong IntuitionBase;
Xlong GfxBase;
Xlong ArpBase;
X
Xstruct FileRequester *FileReq = NULL;
XPORT *MailPort = NULL;
X
XBYTE SpeakPlease = 2, WindowPlease = 2;
X
Xmain(ac,av)
Xchar *av[];
X{
X    long chan = NULL;
X    unsigned long numsecs = 0L;
X    BYTE firstrun = 1, quit = 0;
X    char *host = NULL;
X
X    ArpBase = (long)OpenLibrary(ArpName,39L);
X    if (ArpBase == NULL) exit(1);
X
X    if (!param(ac,av,&numsecs,&firstrun,&quit,&host)) {
X       CloseLibrary(ArpBase);
X       exit(0);
X    }
X    {
X      char buf[64];
X      PORT *pr;
X
X      sprintf(buf, "MailChkV%s%s", VERSION, MAILCHK_VERSION);
X      Enable_Abort = 0;
X      if (pr = FindPort(buf)) {
X	  PORT *mailrp;
X	  struct mailmsg *mailmsg;
X
X	  if (!(mailrp = CreatePort(NULL,0))) goto fail;
X	  if (!(mailmsg = (struct mailmsg *) AllocMem(sizeof(struct mailmsg),
X						MEMF_PUBLIC))) {
X		DeletePort(mailrp);
X		goto fail;
X	  }
X	  mailmsg->ml_msg.mn_Node.ln_Type = NT_MESSAGE;
X	  mailmsg->ml_msg.mn_Length = sizeof(struct mailmsg);
X	  mailmsg->ml_msg.mn_ReplyPort = mailrp;
X	  mailmsg->secs = numsecs;
X	  mailmsg->quit = quit;
X	  mailmsg->speak = SpeakPlease;
X	  mailmsg->win = WindowPlease;
X	  PutMsg(pr,mailmsg);
X	  Wait(1 << mailrp->mp_SigBit | SIGBREAKF_CTRL_C);
X	  DeletePort(mailrp);
X	  FreeMem(mailmsg,sizeof(struct mailmsg));
X	  if (quit) Printf("Mailchk, removed\n");
X	  else Printf("Mailchk, changed parameters\n");
X	  goto fail;
X      }
X      else if (!(MailPort = CreatePort(buf,0))) goto fail;
X    }
X    Printf("\nMailChk V%s%s - S. Laroche 1990\n", VERSION, MAILCHK_VERSION);
X    if (numsecs == 0) numsecs = 40L;
X    if (SpeakPlease == 2) SpeakPlease = 1;
X    if (WindowPlease == 2) WindowPlease = 1;
X    IntuitionBase = (long)OpenLibrary("intuition.library", 0);
X    GfxBase = (long)OpenLibrary("graphics.library", 0);
X    chan = DOpen(host, PORT_MAILCHK, 0, 0);
X    if (chan == NULL) {
X	Puts("no connect");
X	goto fail;
X    }
X
X    if ((FileReq = ArpAllocFreq()) == NULL) goto fail;
X    FileReq->fr_Hail = "Save message to which file?";
X    FileReq->fr_Dir = "MAIL:";
X    InitDeemuNW(Deemu+DMNWOFF, &Nw);
X    if (initmailserver(chan,numsecs,firstrun))
X	 checkmail(chan,numsecs);
X
Xfail:
X    if (Win)
X	CloseWindow(Win);
X    if (MailPort)
X	DeletePort(MailPort);
X    if (chan)
X	DClose(chan);
X    if (IntuitionBase)
X	CloseLibrary(IntuitionBase);
X    if (GfxBase)
X	CloseLibrary(GfxBase);
X    if (ArpBase)
X	CloseLibrary(ArpBase);
X}
X
Xint param(ac,av,numsecs,firstrun,quit,host)
X
Xchar *av[];
XBYTE *firstrun, *quit;
Xunsigned long *numsecs;
XULONG *host;
X
X{
X      register short i;
X      for (i = 1; i < ac; ++i) {
X	if (strncmp(av[i],"-h",2) == 0) {
X	    Printf("DNET    - (C) Matthew Dillon 1988\n");
X	    Printf("\nUsage:  -t(time) Interval between checks in seconds [DEFAULT = 40 seconds]\n");
X	    Printf("        -N(network id) Dnet network number\n");
X	    Printf("        -s(flag) 0 = do not speak, 1 = speak [DEFAULT]\n");
X	    Printf("        -w(flag) 0 = no window, 1 = window [DEFAULT]\n");
X	    Printf("        -d Display mailbox on start-up [Default]\n");
X	    Printf("        -n Don't display mailbox on start-up\n");
X	    Printf("        -q Remove the MailChk client, if it is running\n");
X	    Printf("        -h This message...\n");
X	    return(0);
X	}
X	if (strncmp(av[i], "-N", 2) == 0) {
X	    *host = (ULONG) av[i]+2;
X	    continue;
X	}
X	if (strncmp(av[i],"-d",2) == 0) {
X	    *firstrun = 1;
X	    continue;
X	}
X	if (strncmp(av[i],"-n",2) == 0) {
X	    *firstrun = 0;
X	    continue;
X	}
X	if (strncmp(av[i],"-t",2) == 0) {
X	    *numsecs = atoi(av[i]+2);
X	    continue;
X	}
X	if (strncmp(av[i],"-q",2) == 0) {
X	    *quit = 1;
X	    break;
X	}
X	if (strncmp(av[i],"-s",2) == 0) {
X	    SpeakPlease = (BYTE) atoi(av[i]+2);
X	    continue;
X	}
X	if (strncmp(av[i],"-w",2) == 0) {
X	    WindowPlease = (BYTE) atoi(av[i]+2);
X	    continue;
X	}
X      }
X      return(1);
X}
X
Xinitmailserver(chan,numsecs,firstrun)
X
Xlong chan, numsecs;
Xchar firstrun;
X
X{
X  char init = 4;
X
X    if ((DWrite(chan,&init,1) == 1) && (DWrite(chan,&numsecs,4) == 4)
X	 && (DWrite(chan,&firstrun,1) == 1)) return(1);
X    return(0);
X
X}
X
Xcheckmail(chan,numsecs)
X
Xlong chan, numsecs;
X
X{
X    long imask=0, dmask, omask, mask;
X    char notdone = 1, nowindow = 0;
X    ULONG prsec = 0, prmic = 0;
X    BYTE pos = 0, oldpos = 0;
X
X    dmask   = 1 << ((PORT *) chan)->mp_SigBit;
X    omask   = 1 << MailPort->mp_SigBit;
X    imask   = 0;
X    while (notdone) {
X	if (Win) {
X	    OnMenu(Win,MENUSTRIP(0));
X	    OnMenu(Win,MENUSTRIP(1));
X	}
X	mask = Wait(imask|dmask|omask|SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_E);
X	if (Win) {
X	    OffMenu(Win,MENUSTRIP(0));
X	    OffMenu(Win,MENUSTRIP(1));
X	}
X	if (mask & SIGBREAKF_CTRL_C) {
X	    notdone = 0; break; }
X	if (mask & omask) {
X	    struct mailmsg *msg;
X	    BYTE quit = 0;
X
X	    while (msg = (struct mailmsg *) GetMsg(MailPort)) {
X	      if (msg->secs > 0) numsecs = msg->secs;
X	      quit |= msg->quit;
X	      if (msg->speak < 2) SpeakPlease = msg->speak;
X	      if (msg->win < 2) WindowPlease = msg->win;
X	      ReplyMsg(msg);
X	      if (msg->win == 1 || msg->speak == 1 || msg->secs > 0 || Win == NULL)
X		  initmailserver(chan,numsecs,2);
X	    }
X	    if (quit) { notdone = 0; break; }
X	}
X	if (mask & SIGBREAKF_CTRL_E) {
X	    initmailserver(chan,numsecs,2);
X	    continue;
X	}
X	if (mask & imask) {
X	    IMESS *im;
X	    ULONG class, code;
X
X	    while (im = (IMESS *) GetMsg(Win->UserPort)) {
X		class = im->Class;
X		switch(class) {
X		case NEWSIZE:
X		    dispnewmail(pos,0,1);
X		    break;
X		case MOUSEBUTTONS:
X		    if (im->Code == SELECTUP) {
X		      if (DoubleClick(prsec,prmic,im->Seconds,im->Micros)
X			  && pos == oldpos) {
X			if (pos > 0) {
X			    getmailmsg(chan,pos,0);
X			}
X		      }
X		      else {
X			  prsec = im->Seconds;
X			  prmic = im->Micros;
X			    }
X		      if (pos == 0) dispnewmail(0,oldpos,0);
X		      else oldpos = pos;
X		    }
X		    else if (im->Code == SELECTDOWN) {
X			     register short i=1;
X			     short temp;
X			     struct MailMsg *p = MailP;
X
X			     temp = (im->MouseY - Win->BorderTop) / Rp->TxHeight + 1;
X			     while ( i != temp && p != NULL) {
X				i++;
X				p = p->next;
X			     }
X			     if (p == NULL) { oldpos = pos; pos = 0;}
X			     else { pos = temp;
X				    dispnewmail(pos,oldpos,0);
X				  }
X			 }
X		    break;
X		case CLOSEWINDOW:
X		    nowindow = 1;
X		    break;
X		case MENUPICK:
X		    code = im->Code;
X		    ReplyMsg(im);
X		    switch((uword)((MENUNUM(code)<<8)|ITEMNUM(code))) {
X		    case 0x0100:    /*	View	*/
X			getmailmsg(chan,pos,0);
X			break;
X		    case 0x0101:    /*	Print	*/
X			getmailmsg(chan,pos,1);
X			break;
X		    case 0x0102:    /*	Delete	*/
X			delmailmsg(chan,pos);
X			break;
X		    case 0x0103:    /*	Save	*/
X			getmailmsg(chan,pos,2);
X			break;
X		    case 0x0104:    /*	Speak	*/
X			getmailmsg(chan,pos,3);
X			break;
X		    case 0x0105:    /*	Reply	*/
X			editmessage(chan,pos);
X			break;
X		    case 0x0106:    /*	Send	*/
X			break;
X		    case 0x0000:
X			sprintf(Title, "MailChk V%s%s - S. Laroche 1990", VERSION, MAILCHK_VERSION);
X			SetWindowTitles(Win,Title,-1);
X			break;
X		    case 0x0001:    /*	Close	*/
X			nowindow = 1;
X			break;
X		    case 0x0002:    /*	Talk	*/
X			SpeakPlease = 1 - SpeakPlease;
X			break;
X		    case 0x0003:    /*	Window	*/
X			WindowPlease = 1 - WindowPlease;
X			break;
X		    case 0x0004:    /*	Frequency */
X			break;
X		    case 0x0005:    /*	Remove	*/
X			notdone = 0;
X			break;
X		    }
X		}
X		if (class != MENUPICK) ReplyMsg(im);
X	    }
X	}
X	if (mask & dmask) {
X	    char len = 0;
X
X	    if (DNRead(chan, &len, 1) != 0) {
X		if (len < sizeof(Title) && DRead(chan, Title, len) == len) {
X		    Title[len-1] = 0;
X		    if (strncmp(Title,"No mail",7) == 0) nowindow = 1;
X		    else { if (strncmp(Title,"New mail",8) == 0) {
X			       DisplayBeep(NULL);
X			   }
X			   if (Win == NULL && WindowPlease) {
X			       Win = OpenWindow(&Nw);
X			       if (Win != NULL) {
X				   struct MenuItem *mn_ad;
X				   Rp = Win->RPort;
X				   refreshmenu();
X				   SetMenuStrip(Win,Menu);
X				   OffMenu(Win,MENUSTRIP(0));
X				   OffMenu(Win,MENUSTRIP(1));
X				   imask   = 1 << Win->UserPort->mp_SigBit;
X			       }
X			   }
X			   if (SpeakPlease) {
X			       char *Speaker;
X			       struct FileHandle *fh;
X
X			       Speaker = GetDEnv("SPEAKER");
X			       if (Speaker == NULL) Speaker = DefaultSpeaker;
X			       fh = Open(Speaker,1006);
X			       if (fh) {
X				   if (strncmp(Title,"New",3) == 0)
X				       Write(fh,"You have new mail.",18);
X				   else Write(fh,"You have mail.",14);
X				   Close(fh);
X			       }
X			   }
X			   if (Win) {
X			     short temp=0;
X			     char buf[25], buf2[9];
X
X			     WindowToFront(Win);
X			     getnewmail(chan,&temp);
X			     if (temp > 1) strcpy(buf2,"messages");
X			     else strcpy(buf2,"message");
X			     sprintf(buf," (%d %s)",temp,buf2);
X			     strcat(Title,buf);
X			     dispnewmail(0,0,1);
X			   }
X			   if (Win != NULL) SetWindowTitles(Win, Title, -1);
X			   else if (!SpeakPlease) {
X				    short dummy =0;
X				    Puts(Title);
X				    getnewmail(chan,&dummy);
X				    dispnewmail(0,0,1);
X				}
X		    }
X		}
X	    }
X	    else if (DCheckEof(chan)) notdone = 0;
X	}
X	if (nowindow && Win) {
X	    ClearMenuStrip(Win);
X	    Nw.LeftEdge = Win->LeftEdge;
X	    Nw.TopEdge = Win->TopEdge;
X	    Nw.Width = Win->Width;
X	    Nw.Height = Win->Height;
X	    CloseWindow(Win);
X	    Win = NULL;
X	    imask = 0;
X	}
X	nowindow = 0;
X    }
X
X    freemail(MailP);
X    if (Win) {
X	ClearMenuStrip(Win);
X	CloseWindow(Win);
X	Win = NULL;
X    }
X}
X
X/*
X *  Utility routines.	************************************************
X */
X
Xrefreshmenu()
X
X{
X   struct MenuItem *mn_ad;
X
X   mn_ad = (struct MenuItem *) ItemAddress(Menu,SHIFTMENU(0)|SHIFTITEM(2));
X   if (SpeakPlease) mn_ad->Flags |= CHECKED;
X   else mn_ad->Flags &= ~(CHECKED);
X   mn_ad = (struct MenuItem *) ItemAddress(Menu,SHIFTMENU(0)|SHIFTITEM(3));
X   if (WindowPlease) mn_ad->Flags |= CHECKED;
X   else mn_ad->Flags &= ~(CHECKED);
X}
X
Xgetnewmail(chan,count)
X
Xlong chan;
Xregister short *count;
X
X{
X  unsigned char len = 1;
X  struct MailMsg *p;
X
X  freemail(MailP);
X  if (DWrite(chan, &len, 1) == 1 && DRead(chan, &len, 1) == 1) {
X      while (len > 0) {
X	if (MailP) {
X	    p->next = AllocMem(sizeof(*p),0);
X	    p = p->next;
X	}
X	else {
X	    MailP = AllocMem(sizeof(*p),0);
X	    p = MailP;
X	}
X	if (p == NULL) break;
X	else p->next = NULL;
X	if (len < MAILLENGTH && (DRead(chan, p->msg, len) == len)) {
X	    p->msg[len-1] = '\0';
X	    DRead(chan,&len,1);
X	    (*count)++;
X	}
X	else break;
X
X      }
X  }
X}
X
Xdispnewmail(ONmsgno,OFFmsgno,flag)
X
XBYTE ONmsgno, OFFmsgno, flag;
X
X{
X  char th, tb, tw;
X  short y, Wh, Ww, WOx, WOy;
X  int len;
X  struct MailMsg *p;
X  BYTE i=1;
X
X  p = MailP;
X  if (Win != NULL) {
X      th = Rp->TxHeight;
X      tb = Rp->TxBaseline;
X      tw = Rp->TxWidth;
X      y = Win->BorderTop;
X      Ww = Win->Width - Win->BorderRight - Win->BorderLeft;
X      Wh = Win->Height- Win->BorderTop - Win->BorderBottom;
X      WOx = Win->BorderLeft;
X      WOy = Win->BorderTop;
X      if (flag) {
X	  SetAPen(Rp, 0);
X	  RectFill(Rp, WOx, WOy, Ww + WOx, Wh + WOy);
X      }
X  }
X  while (p != NULL && ((Win == NULL) || ((y+tb) < Wh))) {
X    short tl;
X
X    if (! Win && flag) Puts(p->msg);
X    else { if (flag || i == ONmsgno || i == OFFmsgno) {
X	       if (ONmsgno == i) {
X		   SetBPen(Rp,2);
X		   SetAPen(Rp,0);
X	       }
X	       else {
X		   SetAPen(Rp,2);
X		   SetBPen(Rp,0);
X	       }
X	       len = strlen(p->msg);
X	       tl = TextLength(Rp,p->msg,len);
X	       if (tl > Ww) len = Ww / tw;
X	       Move(Rp,Win->BorderLeft,y+tb);
X	       Text(Rp,p->msg,len);
X	       if (ONmsgno == i) SetAPen(Rp,2);
X	       else if (OFFmsgno == i || flag) SetAPen(Rp,0);
X	       RectFill(Rp,Rp->cp_x,y,Ww+WOx,y+th-1);
X	   }
X	   y += th;
X	   i++;
X    }
X    p = p->next;
X  }
X}
X
Xdelmailmsg(chan,msgno)
X
Xlong chan;
XBYTE msgno;
X
X{
X  register BYTE i=1;
X  struct MailMsg *p = MailP;
X  char dummy[32];
X  BYTE dl = 3, ok;
X  unsigned long stchar = 0,nochars;
X
X  for (i=1; (i != msgno && p != NULL); i++) {
X    getmailprm(p,&nochars,dummy);
X    stchar += nochars;
X    p = p->next;
X  }
X  if (p == NULL) return();
X  getmailprm(p,&nochars,dummy);
X
X  if ((DWrite(chan,&dl,1) == 1) &&
X      (DWrite(chan,&stchar,4) == 4) &&
X      (DWrite(chan,&nochars,4) == 4) &&
X      (DRead(chan,&ok,1) == 1)) {
X      if (ok) {
X	  freemail(MailP);
X	  strcpy(Title,"Delete successful, refreshing...");
X	  SetWindowTitles(Win,Title,-1);
X	  dispnewmail(0,0,1);
X      }
X  }
X}
X
Xint getmailmsg(chan,msgno,flag)
X
Xlong chan;
XBYTE msgno, flag;
X
X{
X  struct MailMsg *p = MailP;
X  BYTE i, ok=0, hd = 2, l, start = 0;
X  unsigned long stchar=0L, nochars, len;
X  long fh;
X  ubyte *buf;
X  char pname[128], vname[100], title[132], *tmp;
X  int rcode = 1;
X  struct NewShell *NS;
X  if (NS = AllocMem(sizeof(*NS)+4096,MEMF_CLEAR)) {
X      NS->nsh_StackSize = 4000;
X      NS->nsh_Control = BACKGROUND_SHELL;
X  }
X  else return(rcode);
X  strcpy(vname,"DPIPE:Mail");
X  switch (flag) {
X    case 0:
X      if ((tmp = GetDEnv("PAGER")) == NULL) {
X	  strcpy(pname,"sys:utilities/more");
X      }
X      else { strcpy(pname,tmp);
X	     free(tmp);
X      }
X      strcat(pname," ");
X      strcat(pname,vname);
X      strcpy(title,"Viewing ");
X      start = 1;
X      break;
X    case 1:
X      strcpy(vname,"PRT:");
X      strcpy(title,"Printing ");
X      break;
X    case 2:
X      if (!(FileRequest(FileReq))) {
X	    return(rcode);}
X      strcpy(vname,FileReq->fr_Dir);
X      TackOn(vname,FileReq->fr_File);
X      strcpy(title,"Saving ");
X      strcat(title,vname);
X      break;
X    case 3:
X      tmp = GetDEnv("SPEAKER");
X      if (tmp == NULL) tmp = DefaultSpeaker;
X      strcpy(vname,tmp);
X      strcpy(title,"Speaking ");
X      break;
X  }
X  buf = (ubyte *) (NS + sizeof(*NS));
X  l = strlen(title);
X  for (i=1; (i != msgno && p != NULL); i++) {
X    getmailprm(p,&nochars,&len);
X    stchar += nochars;
X    p = p->next;
X  }
X  if (p == NULL) return(rcode);
X  getmailprm(p,&nochars,&len);
X  if (flag == 3) {stchar += len; nochars -= len; }
X  if (flag == 0) {
X      strcat(title," using ");
X      strcat(title,pname);
X  }
X  if (fh = Open(vname,1006)) {
X      if (DWrite(chan, &hd, 1) == 1 && DWrite(chan, &stchar, 4) == 4
X	  && DWrite(chan,&nochars,4) == 4) {
X	  SetWindowTitles(Win, title, -1);
X	  while (DRead(chan,&len,4) == 4 && len > 0) {
X	    if (DRead(chan,buf,len) == len) {
X		if (start) {
X		    if (ASyncRun(pname,0L,NS) < 0) {
X			ok = 1;
X			DWrite(chan,&ok,1);
X			rcode = 0;
X			break;
X		    }
X		    start = 0;
X		}
X		if (Write(fh,buf,len) != len) {
X		    ok = 1;
X		    DWrite(chan,&ok,1);
X		    rcode = 0;
X		    break;
X		}
X		DWrite(chan,&ok,1);
X	    }
X	  }
X      }
X      Close(fh);
X  }
X  else {
X	rcode = 0;
X	Printf("\nCould not open %s\n",vname);
X  }
X  SetWindowTitles(Win,Title,-1);
X  FreeMem(NS,sizeof(*NS)+4096);
X  return(rcode);
X}
X
Xint editmessage(chan,msgno)
X
Xlong *chan;
XUBYTE msgno;
X
X{
X  char *buf, fname[32];
X  struct MailMsg *p = MailP;
X  int ok = 0, test;
X  struct FileInfoBlock *fileinfo;
X  struct FileLock *lock;
X  struct FileHandle *fh = NULL;
X  LONG len;
X  short count;
X  BYTE hd = 5, i;
X
X  if (!(fileinfo = AllocMem(sizeof(struct FileInfoBlock)+BUFLENGTH,0)))
X      return(ok);
X  buf = (char *) (fileinfo + sizeof(struct FileInfoBlock));
X  strcpy(fname,"T:MailChk");
X  strcpy(Title,"Replying...");
X  SetWindowTitles(Win,Title,-1);
X  if (GetDEnv("EDITOR") != NULL) strcpy(buf,GetDEnv("EDITOR"));
X  else strcpy(buf,"ed");
X  if (SyncRun(buf,fname,0,0) >= 0) {
X      if (((lock = Lock(fname,ACCESS_READ)) != 0) &&
X	Examine(lock,fileinfo)) {
X	len = fileinfo->fib_Size;
X	UnLock(lock);
X	strcpy(Title,"Could not open tmp file");
X	if (!(fh = Open(fname,1005))) goto fin;
X	strcpy(Title,"Inconsistency error");
X	for (i=1; (i != msgno && p != NULL); i++)
X	     p = p->next;
X	if (p == NULL) goto fin;
X	sscanf(p->msg+1,"%d %s",&test,buf);
X	if (test != msgno) goto fin;
X	strcpy(Title,"Transmission error");
X	if (DWrite(chan,&hd,1) != 1) goto fin;
X	count = strlen(buf);
X	if (DWrite(chan,&count,2) != 2) goto fin;
X	if (DWrite(chan,buf,count) != count) goto fin;
X	if (DWrite(chan,&len,4) != 4) goto fin;
X	do {
X	  count = Read(fh,buf,BUFLENGTH);
X	  if (count > 0 && DWrite(chan,buf,count) != count) goto fin;
X	} while (count == BUFLENGTH);
X	strcpy(Title,"Remote error");
X	if (DRead(chan,&ok,1) != 1) ok = 0;
X      }
X      else {
X	  strcpy(Title,"Reply function cancelled");
X	  goto fin2;
X      }
X  }
X  else { sprintf(Title,"Editor %s not found",buf);
X	 goto fin2;
X  }
Xfin:
X  if (fh) Close(fh);
X  if (ok) {
X      DeleteFile(fname);
X      strcpy(Title,"Reply was suscessful");
X  }
X  else {
X      DeleteFile("T:dead.letter");
X      Rename(fname,"T:dead.letter");
X      strcat(Title," - Letter is in T:dead.letter");
X  }
Xfin2:
X  SetWindowTitles(Win,Title,-1);
X  FreeMem(fileinfo,sizeof(struct FileInfoBlock)+BUFLENGTH);
X  return(ok);
X}
X
Xgetmailprm(p,nochars,len)
X
Xstruct MailMsg *p;
Xunsigned long *nochars, *len;
X
X{
X  char *str;
X
X  if (str = rindex(p->msg,'/')) {
X      sscanf(++str,"%ld %ld",nochars,len);
X  }
X  else *nochars = 0;
X}
X
Xfreemail(p)
X
Xstruct MailMsg *p;
X
X{
X  while (p != NULL) {
X    FreeMem(p,sizeof(*p));
X    p = p->next;
X  }
X  MailP = NULL;
X}
X
X
END_OF_FILE
if test 18325 -ne `wc -c <'amiga/client/mailchk.c'`; then
    echo shar: \"'amiga/client/mailchk.c'\" unpacked with wrong size!
fi
# end of 'amiga/client/mailchk.c'
fi
if test -f 'amiga/client/mailmenu.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/client/mailmenu.h'\"
else
echo shar: Extracting \"'amiga/client/mailmenu.h'\" \(2312 characters\)
sed "s/^X//" >'amiga/client/mailmenu.h' <<'END_OF_FILE'
XITEXT IText1[] = {
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Version"        },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Close"          },
X    { 0, 1, JAM2, CHECKWIDTH, 0, NULL, (ubyte *)"Talk"  },
X    { 0, 1, JAM2, CHECKWIDTH, 0, NULL, (ubyte *)"Window"},
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Frequency"      },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Remove"         }
X};
X
XITEXT IText2[] = {
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"View"           },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Print"          },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Delete"         },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Save"           },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Speak"          },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Reply"          },
X    { 0, 1, JAM2, 0, 0, NULL, (ubyte *)"Send"           }
X};
X
X
XITEM Item1[] = {
X    { &Item1[1], 0, 0, 100, 10, ITEMTEXT|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText1[0], NULL },
X    { &Item1[2], 0,10, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText1[1], NULL, 'C' },
X    { &Item1[3], 0,20, 100, 10, ITEMTEXT|MENUTOGGLE|CHECKIT|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText1[2], NULL },
X    { &Item1[4], 0,30, 100, 10, ITEMTEXT|MENUTOGGLE|CHECKIT|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText1[3], NULL },
X    { &Item1[5], 0,40, 100, 10, ITEMTEXT|HIGHCOMP, 0, (APTR)&IText1[4], NULL },
X    { NULL     , 0,50, 100, 10, ITEMTEXT|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText1[5], NULL }
X};
X
XITEM Item2[] = {
X    { &Item2[1], 0, 0, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText2[0], NULL, 'V' },
X    { &Item2[2], 0,10, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText2[1], NULL, 'P' },
X    { &Item2[3], 0,20, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText2[2], NULL, 'D' },
X    { &Item2[4], 0,30, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText2[3], NULL, 'S' },
X    { &Item2[5], 0,40, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText2[4], NULL, 'T' },
X    { &Item2[6], 0,50, 100, 10, ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP, 0, (APTR)&IText2[5], NULL, 'R'},
X    { NULL     , 0,60, 100, 10, ITEMTEXT|HIGHCOMP, 0, (APTR)&IText2[6], NULL}
X};
X
XMENU Menu[] = {
X    { &Menu[1], 0, 0, 100, 10+50, MENUENABLED, "Project", &Item1[0] },
X    { NULL    , 110, 0, 100, 10+60, MENUENABLED, "Mail", &Item2[0] }
X};
X
X
END_OF_FILE
if test 2312 -ne `wc -c <'amiga/client/mailmenu.h'`; then
    echo shar: \"'amiga/client/mailmenu.h'\" unpacked with wrong size!
fi
# end of 'amiga/client/mailmenu.h'
fi
if test ! -d 'amiga/doc' ; then
    echo shar: Creating directory \"'amiga/doc'\"
    mkdir 'amiga/doc'
fi
if test -f 'amiga/doc/mailchk.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/doc/mailchk.doc'\"
else
echo shar: Extracting \"'amiga/doc/mailchk.doc'\" \(5353 characters\)
sed "s/^X//" >'amiga/doc/mailchk.doc' <<'END_OF_FILE'
XAMIGA/MAILCHK
X
X    MAILCHK [-Nnet] [-tupdatetime] [-d] [-n] [-h] [-s#] [-w#] [-q]
X
X    The -N option specifies the network (default = 0).  This is the same
X    network as was specified when you ran DNET (if was not specified, is 0)
X
X    The -t option specifies the time between checks [DEFAULT = 40s].
X    The -d option notifies MAILCHK that you want to see your mailbox
X                  on startup [DEFAULT].
X    The -n option specifies no mailbox on startup
X    The -h option displays a help message.
X    The -s option selects speech:
X           -s0 = Do not speak.
X           -s1 = Say things like "You have mail"... [DEFAULT]
X    The -w option selects nowindow/window:
X           -w0 = Do not open a window when mail is received.
X           -w1 = Open a window to display mailbox.  [DEFAULT]
X    The -q option removes the client.  It has no effect if MailChk was
X                  not already running. 
X
X
X    With MAILCHK, you may view letters using you favorite text viewer. 
XThis viewer must be able to read from the DPIPE: device.  I know that TY
Xand MUCHMORE work as expected.  LessV1.3 DOES NOT WORK with the DPIPE:
X(or the PIPE:) device.  The default viewer is SYS:UTILITIES/More.  To
Xchange it, use SETENV PAGER "path/your viewer".  The DPIPE: device must be
Xmounted for this option to work.
X
XNOTE:  You need ARP.LIBRARY V39.1 to run this program.
X------------------------------------------------------ 
X
XDescription of the switches:
X============================
X
X    The server process on the Unix end must check periodically for new
Xmail.  The -t switch sets the frequency of those checks.  If speech is
Xselected (-s1), the program will use the SPEAK: device to say "You have
Xmail" or "New mail has arrived".  If the -w0 switch is selected, then
Xno window will be opened when mail arrives. In the case of -s0 -w0 being
Xselected, what would have appeared in a window is redirected to the
Xstandard output.
X    The -q switch removes Mailchk.  All the above settings can be
Xmodified at any time by calling the program with the desired switches.
XEg.
X        run mailchk -s0 -t15       ; do not speak, frequency 15 seconds
X        mailchk -s1 -w0            ; speak, but do not open a window
X        mailchk -q                 ; done with the mail client...
X
XDescription of the menus:
X=========================
X
X    There are two menus, Project and Mail.
X
XProject:
X          
X   Version:  Simply prints the version number and the author's name in
X             the window's title bar.    
X
X   Talk   :  Toggle that have the same function as the -s switch
X
X   Window :  Toggle that have the same function as the -w switch
X
X   Close  :  Close the window (What else...).  Mailchk will still be
X             running.  (same effect as the close gadget).
X
X   Remove :  Same effect as typing "mailchk -q" in a CLI.  The client is
X             removed (killed).
X
XMail:
X
X   View   :  View a message previously selected with the mouse.  The
X             text viewer used is More.  If you prefer another viewer,
X             then setenv PAGER to the name of the viewer.
X             Eg. setenv PAGER 'MuchMore'
X             Note:  LessV1.3 does not work with the DPIPE: device, which
X                    just reminded me that the DPIPE: device must be
X                    mounted for this option to work.
X
X   Print  :  Output the selected letter to the PRT: device.
X  
X   Delete :  Remove the selected message from your Unix mailbox.
X             Look in the DNET.LOG file for any errors...
X
X   Save   :  Save the selected message.  This option uses the ARP
X             file requester.
X
X   Speak  :  Send the selected message to the SPEAK:, which must be
X             mounted.  Only the actual message is sent (No use in
X             hearing a bunch of numbers or some unpronouncable
X             addresses, don't you think?).
X             If the environnement variable SPEAKER is set, its value 
X             is taken as the name of the device.
X             Eg. setenv SPEAKER 'SPEAK:opt/f'
X
X   Reply  :  Replies to the selected message using your favorite editor.
X             The program will use 'ed' unless you specified another
X             editor in the environnement variable EDITOR.  
X             You may cancel the operation by quitting the editor without
X             saving.  If for any reasons the reply could not be sent,
X             your letter will be saved in the T: directory under the
X             name "dead.letter".
X
X
XBUGS
X
X    The DPIPE: device seems to choke on big transfers. 
Xavoid reading files that contain a uuencoded program...
XIf the PIPE: device was working with ARP, it would also have simplified
Xthings a bit.
X
XDISCLAIMER
X
X    I offer no guarantee that this program will work as advertised.
XThis program is subject to the same distributions conditions specified 
Xin the Dnet documentation.    
X
XNOTE FROM THE PROGRAMMER
X
X    I will continue to improve MailChk.  For this reason, any
Xsuggestions or improvements should be sent to me to ensure that only one
X'official' version exists and that it is the best one.
X
X    Things to look for in future versions:
X       ...An iconize option using a mailbox as icon.
X       ...A send option (that one is easy!).
X       ...A better narrator.device!?!
X
X
XStephane Laroche
XMarch 19, 1990
X
XBITNET:  B85O@MUSICB.MCGILL.BITNET
X
XBefore (september 1990):  lobster@calvin.cs.mcgill.ca
X    
END_OF_FILE
if test 5353 -ne `wc -c <'amiga/doc/mailchk.doc'`; then
    echo shar: \"'amiga/doc/mailchk.doc'\" unpacked with wrong size!
fi
# end of 'amiga/doc/mailchk.doc'
fi
if test ! -d 'amiga/server' ; then
    echo shar: Creating directory \"'amiga/server'\"
    mkdir 'amiga/server'
fi
if test -f 'amiga/server/servers.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/server/servers.h'\"
else
echo shar: Extracting \"'amiga/server/servers.h'\" \(643 characters\)
sed "s/^X//" >'amiga/server/servers.h' <<'END_OF_FILE'
X
X/*
X *  SERVERS.H
X *
X *  DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
X *
X */
X
X#include "/version.h"
X
X#define PORT_FILECOPY	8192
X#define PORT_ALPHATERM	8193
X#define PORT_ECHO	8194
X#define PORT_IALPHATERM 8195
X#define PORT_AMIGASHELL 8196
X#define PORT_LOADAV	8197
X#define PORT_PRINTER	8198
X#define PORT_PASSWD	8199
X#define PORT_BBS	8200
X#define PORT_GFILECOPY	8201
X#define PORT_MAILCHK    8204
X
X#define DNET_WRITE  "DNET_WRITE"
X#define DNET_READ   "DNET_READ"
X#define DNET_LEVEL  "DNET_LEVEL"
X#define DNET_GROUP  "DNET_GROUP"
X
X#define FS_GROUP    "GR="   /*  MUST INCLUDE '=' cause I use strncmp()  */
X#define FS_ACCESS   "AC="
X
END_OF_FILE
if test 643 -ne `wc -c <'amiga/server/servers.h'`; then
    echo shar: \"'amiga/server/servers.h'\" unpacked with wrong size!
fi
# end of 'amiga/server/servers.h'
fi
if test -f 'amiga/version.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'amiga/version.h'\"
else
echo shar: Extracting \"'amiga/version.h'\" \(527 characters\)
sed "s/^X//" >'amiga/version.h' <<'END_OF_FILE'
X
X#define VERSION 	    "2.01"
X
X#define DNET_VERSION	    ".10"
X#define STATDNET_VERSION    ".04"
X#define PUTFILES_VERSION    ".03"
X#define LOADAV_VERSION	    ".05"
X#define FTERM_VERSION	    ".04"
X#define QUITDNET_VERSION    ".01"
X#define GETFILES_VERSION    ".02"
X#define CLITERM_VERSION     ".01"
X#define MAILCHK_VERSION     ".03"
X
X#define SPRINT_VERSION	    ".01"
X#define SGCOPY_VERSION	    ".01"
X#define SCOPY_VERSION	    ".03"
X#define STERM_VERSION	    ".03"
X#define SCLI_VERSION	    ".02"
X#define SPASSWD_VERSION     ".01"
X
END_OF_FILE
if test 527 -ne `wc -c <'amiga/version.h'`; then
    echo shar: \"'amiga/version.h'\" unpacked with wrong size!
fi
# end of 'amiga/version.h'
fi
if test ! -d 'unix' ; then
    echo shar: Creating directory \"'unix'\"
    mkdir 'unix'
fi
if test -f 'unix/README.SMAILCHK' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/README.SMAILCHK'\"
else
echo shar: Extracting \"'unix/README.SMAILCHK'\" \(143 characters\)
sed "s/^X//" >'unix/README.SMAILCHK' <<'END_OF_FILE'
X
XThe version of dnetlib.c is 2.10.  If you are using a different version,
Xit might be wise to place the correct version of dnetlib.c in lib/ .
END_OF_FILE
if test 143 -ne `wc -c <'unix/README.SMAILCHK'`; then
    echo shar: \"'unix/README.SMAILCHK'\" unpacked with wrong size!
fi
# end of 'unix/README.SMAILCHK'
fi
if test ! -d 'unix/doc' ; then
    echo shar: Creating directory \"'unix/doc'\"
    mkdir 'unix/doc'
fi
if test -f 'unix/doc/smailchk.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/doc/smailchk.doc'\"
else
echo shar: Extracting \"'unix/doc/smailchk.doc'\" \(784 characters\)
sed "s/^X//" >'unix/doc/smailchk.doc' <<'END_OF_FILE'
X
X
XUNIX/SMAILCHK
X
X
X
X	(Port number 8204: MAILCHK client)
X
X        This server handles only one connection.  You must add an entry in
Xyour 'dnet.servers' file for this server.
X
X      Eg:  8204  /u/home/loginname  /u/home/loginname/dnetbin/smailchk
X
X
X	This server expects to find your mailbox in the /usr/spool/mail
Xdirectory.  If, on your system, your mailbox is located in a different
Xplace, then store the path in the environment variable MAIL.
X
X      Eg.  setenv MAIL /var/spool/mail
X
X	There must a unix "mail" program in your path if you want to use
Xthe Reply option from the Amiga.
X
X	To compile the program, type 'make' in the dnet/unix/server
Xdirectory. 
X
X
X
XStephane Laroche
XMarch 19, 1990
X
XINTERNET:  B85O@MUSICB.MCGILL.CA
X
XBefore (september 1990):  lobster@calvin.cs.mcgill.ca
X 
END_OF_FILE
if test 784 -ne `wc -c <'unix/doc/smailchk.doc'`; then
    echo shar: \"'unix/doc/smailchk.doc'\" unpacked with wrong size!
fi
# end of 'unix/doc/smailchk.doc'
fi
if test ! -d 'unix/lib' ; then
    echo shar: Creating directory \"'unix/lib'\"
    mkdir 'unix/lib'
fi
if test -f 'unix/lib/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/lib/Makefile'\"
else
echo shar: Extracting \"'unix/lib/Makefile'\" \(42 characters\)
sed "s/^X//" >'unix/lib/Makefile' <<'END_OF_FILE'
X
X
Xdnetlib.o : dnetlib.c
X	cc -c dnetlib.c
X
END_OF_FILE
if test 42 -ne `wc -c <'unix/lib/Makefile'`; then
    echo shar: \"'unix/lib/Makefile'\" unpacked with wrong size!
fi
# end of 'unix/lib/Makefile'
fi
if test -f 'unix/lib/dnetlib.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/lib/dnetlib.c'\"
else
echo shar: Extracting \"'unix/lib/dnetlib.c'\" \(6103 characters\)
sed "s/^X//" >'unix/lib/dnetlib.c' <<'END_OF_FILE'
X
X/*
X *  DNETLIB.C
X *
X *	DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
X *
X *  Library Interface for DNET.
X */
X
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <fcntl.h>
X#include <signal.h>
X#include <stdio.h>
X#include <errno.h>
X#ifdef O_CREAT
X#include <sys/file.h>
X#endif
X#include "../lib/dnetlib.h"
X
Xextern char *getenv();
X
Xtypedef unsigned short uword;
Xtypedef unsigned long ulong;
Xtypedef unsigned char ubyte;
Xtypedef struct sockaddr SOCKADDR;
X
Xtypedef struct {
X	int s;
X	uword port;
X} CHANN;
X
X#define NAMELEN sizeof(".PORT.XXXXX")
X#define NAMEPAT "%s.PORT.%ld"
X
Xchar *getdirpart();
X
XCHANN *
XDListen(port)
Xuword port;
X{
X    CHANN *chan;
X    int s;
X    SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256);
X    char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
X
X    sprintf(sa->sa_data, NAMEPAT, dirstr, port);
X    sa->sa_family = AF_UNIX;
X    unlink(sa->sa_data);
X
X    s = socket(PF_UNIX, SOCK_STREAM, 0);
X    fcntl(s, F_SETOWN, getpid());
X    if (bind(s, sa, sizeof(*sa)-sizeof(sa->sa_data)+strlen(sa->sa_data)) < 0) {
X	close(s);
X	free(sa);
X	return(NULL);
X    }
X    if (listen(s, 5) < 0) {
X	close(s);
X	unlink(sa->sa_data);
X	free(sa);
X	return(NULL);
X    }
X    chan = (CHANN *)malloc(sizeof(CHANN));
X    chan->s = s;
X    chan->port = port;
X    free(sa);
X    return(chan);
X}
X
X
XDUnListen(chan)
XCHANN *chan;
X{
X    char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
X    char buf[32];
X
X    close(chan->s);
X    sprintf(buf, NAMEPAT, dirstr, chan->port);
X    unlink(buf);
X    free(chan);
X}
X
XDAccept(chan)
XCHANN *chan;
X{
X    SOCKADDR sa;
X    int addrlen = sizeof(sa);
X    int fd;
X
X    fd = accept(chan->s, &sa, &addrlen);
X    return(fd);
X}
X
XDOpen(host, port, txpri, rxpri)
Xchar *host;
Xuword port;
Xchar txpri, rxpri;
X{
X    int s;
X    char rc;
X    short xb[3];
X    SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256);
X    char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
X
X    if (rxpri < -127)
X	rxpri = -127;
X    if (rxpri > 126)
X	rxpri = 126;
X    if (txpri < -127)
X	txpri = -127;
X    if (txpri > 126)
X	txpri = 126;
X
X    if (host == NULL)
X	host = (getenv("DNETHOST")) ? getenv("DNETHOST"):"3";
X
X    sa->sa_family = AF_UNIX;
X    sprintf(sa->sa_data, "%s%s%s", dirstr, "DNET.", host);
X
X    s = socket(PF_UNIX, SOCK_STREAM, 0);
X    fcntl(s, F_SETOWN, getpid());
X    if (connect(s, sa, sizeof(sa->sa_family) + strlen(sa->sa_data)) < 0) {
X	close(s);
X	free(sa);
X	return(-1);
X    }
X    free(sa);
X    xb[0] = port;
X    ((char *)&xb[1])[0] = txpri;
X    ((char *)&xb[1])[1] = rxpri;
X    write(s, xb, 4);
X    if (read(s, &rc, 1) == 1 && rc == 0)
X	return(s);
X    close(s);
X    return(-1);
X}
X
XDEof(fd)
X{
X    char dummy;
X
X    shutdown(fd, 1);
X    write(fd, &dummy, 0);
X}
X
Xgwrite(fd, buf, bytes)
Xchar *buf;
X{
X    int n;
X    int orig = bytes;
X    extern int errno;
X    while (bytes) {
X	n = write(fd, buf, bytes);
X	if (n > 0) {
X	    bytes -= n;
X	    buf += n;
X	    continue;
X	}
X	if (n < 0) {
X	    if (errno == EINTR)
X		continue;
X	    if (errno == EWOULDBLOCK) {
X		int wm = 1 << fd;
X		int em = 1 << fd;
X		if (select(fd+1, NULL, &wm, &em, NULL) < 0)
X		    continue;
X		if (wm)
X		    continue;
X	    }
X	    return(orig - bytes);
X	}
X    }
X    return(orig);
X}
X
Xgread(fd, buf, bytes)
Xchar *buf;
X{
X    int n;
X    int orig = bytes;
X    extern int errno;
X    while (bytes) {
X	n = read(fd, buf, bytes);
X	if (n > 0) {
X	    bytes -= n;
X	    buf += n;
X	    break;
X	}
X	if (n < 0) {
X	    if (errno == EINTR)
X		continue;
X	    if (errno == EWOULDBLOCK) {
X		int rm = 1 << fd;
X		int em = 1 << fd;
X		if (select(fd+1, &rm, NULL, &em, NULL) < 0)
X		    continue;
X		if (rm)
X		    continue;
X	    }
X	    return(orig - bytes);
X	}
X	if (n == 0)
X	    break;
X    }
X    return(orig - bytes);
X}
X
Xggread(fd, buf, bytes)
Xchar *buf;
X{
X    int n;
X    int ttl = 0;
X    while (bytes) {
X	n = gread(fd, buf, bytes);
X	if (n > 0) {
X	    bytes -= n;
X	    buf += n;
X	    ttl += n;
X	    continue;
X	}
X	return(-1);
X    }
X    return(ttl);
X}
X
X/*
X *	Convert to and from 68000 longword format.  Of course, it really
X *	doesn't matter what format you use, just as long as it is defined.
X */
X
Xntohl68(n)
Xulong n;
X{
X    return(
X	(((ubyte *)&n)[0] << 24)|
X	(((ubyte *)&n)[1] << 16)|
X	(((ubyte *)&n)[2] << 8)|
X	(((ubyte *)&n)[3])
X    );
X}
X
Xhtonl68(n)
Xulong n;
X{
X    ulong v;
X    ((ubyte *)&v)[0] = n >> 24;
X    ((ubyte *)&v)[1] = n >> 16;
X    ((ubyte *)&v)[2] = n >> 8;
X    ((ubyte *)&v)[3] = n;
X    return(v);
X}
X
X
XDoOption(ac, av, ops, args)
Xshort ac;
Xchar *av[];
Xchar *ops;
Xlong args;
X{
X    register short i;
X    short j;
X
X    for (i = j = 1; i < ac; ++i) {
X	register char *ptr = av[i];
X	if (*ptr != '-') {
X	    av[j++] = av[i];
X	    continue;
X	}
X	while (*++ptr) {
X	    register char *op;
X	    long **ap = (long **)&args;
X	    short isshort;
X
X	    for (op = ops; *op && *op != *ptr;) {
X		if (*op == *ptr)
X		    break;
X		if (*++op == '%') {
X		    while (*op && *op != 's' && *op != 'd')
X			++op;
X		    if (*op)
X			++op;
X		}
X		if (*op == ',')     /*  optional ,  */
X		    ++op;
X		++ap;
X	    }
X	    if (*op == 0)
X		return(-1);
X	    if (op[1] != '%') {
X		*(short *)*ap = 1;
X		++ap;
X		continue;
X	    }
X	    op += 2;
X	    isshort = 1;
X	    while (*op && *op != 's' && *op != 'd') {
X		switch(*op) {
X		case 'h':
X		    isshort = 1;
X		    break;
X		case 'l':
X		    isshort = 0;
X		    break;
X		default:
X		    return(-1);
X		}
X		++op;
X	    }
X	    switch(*op) {
X	    case 's':
X		if (ptr[1]) {
X		    *(char **)*ap = ptr + 1;
X		    ptr = "\0";
X		} else {
X		    *(char **)*ap = av[++i];
X		}
X		break;
X	    case 'd':
X		if (isshort)
X		    *(short *)*ap = atoi(++ptr);
X		else
X		    *(long *)*ap = atoi(++ptr);
X		while (*ptr >= '0' && *ptr <= '9')
X		    ++ptr;
X		break;
X	    default:
X		return(-1);
X	    }
X	}
X    }
X    return(j);
X}
X
Xelog(how, ctl, arg)
Xchar *ctl;
Xlong arg;
X{
X    char *dir = getenv("DNETDIR");
X    FILE *fi;
X    char buf[256];
X    long dtime;
X
X    time(&dtime);
X
X    if (!dir)
X	dir = "";
X    sprintf(buf, "%s%s", dir, "DNET.LOG");
X    if (fi = fopen(buf, "a")) {
X	strcpy(buf, ctime(&dtime));
X	buf[strlen(buf)-1] = 0;
X	fprintf(fi, "%s ", buf);
X	fprintf(fi, ctl, arg);
X	putc('\n', fi);
X	fclose(fi);
X    }
X    if (how == EFATAL)
X	exit(1);
X}
X
END_OF_FILE
if test 6103 -ne `wc -c <'unix/lib/dnetlib.c'`; then
    echo shar: \"'unix/lib/dnetlib.c'\" unpacked with wrong size!
fi
# end of 'unix/lib/dnetlib.c'
fi
if test -f 'unix/lib/dnetlib.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/lib/dnetlib.h'\"
else
echo shar: Extracting \"'unix/lib/dnetlib.h'\" \(52 characters\)
sed "s/^X//" >'unix/lib/dnetlib.h' <<'END_OF_FILE'
X
X#define EFATAL 0
X#define EWARN 1
X#define EDEBUG 2
X
END_OF_FILE
if test 52 -ne `wc -c <'unix/lib/dnetlib.h'`; then
    echo shar: \"'unix/lib/dnetlib.h'\" unpacked with wrong size!
fi
# end of 'unix/lib/dnetlib.h'
fi
if test ! -d 'unix/server' ; then
    echo shar: Creating directory \"'unix/server'\"
    mkdir 'unix/server'
fi
if test -f 'unix/server/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/server/Makefile'\"
else
echo shar: Extracting \"'unix/server/Makefile'\" \(765 characters\)
sed "s/^X//" >'unix/server/Makefile' <<'END_OF_FILE'
X
X#	DNET SERVERS
X#
X#
X#	DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
X
XNETLIB = ../lib/dnetlib.o
XBIN = ../bin
X
X
X#all:	$(NETLIB) $(BIN)/scopy $(BIN)/sshell \
X#	$(BIN)/sloadav $(BIN)/sgcopy $(BIN)/snfs \
X
Xall:	$(NETLIB) $(BIN)/smailchk 
X
X$(NETLIB) : ../lib/dnetlib.c
X	cc -c ../lib/dnetlib.c
X	mv dnetlib.o ../lib
X
X#$(BIN)/snfs:		snfs.o
X#	cc snfs.o $(NETLIB) -o $(BIN)/snfs
X
X#$(BIN)/scopy:		scopy.o
X#	cc scopy.o $(NETLIB) -o $(BIN)/scopy
X
X#$(BIN)/sgcopy:		sgcopy.o
X#	cc sgcopy.o $(NETLIB) -o $(BIN)/sgcopy
X
X#$(BIN)/sshell:    	sshell.o
X#	cc sshell.o $(NETLIB) -o $(BIN)/sshell
X
X#$(BIN)/sloadav:    	sloadav.o
X#	cc sloadav.o $(NETLIB) -o $(BIN)/sloadav
X
X$(BIN)/smailchk:   	smailchk.o
X	cc smailchk.o $(NETLIB) -o $(BIN)/smailchk
X
Xclean:
X	rm -f *.o make.out
X
END_OF_FILE
if test 765 -ne `wc -c <'unix/server/Makefile'`; then
    echo shar: \"'unix/server/Makefile'\" unpacked with wrong size!
fi
# end of 'unix/server/Makefile'
fi
if test -f 'unix/server/servers.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/server/servers.h'\"
else
echo shar: Extracting \"'unix/server/servers.h'\" \(450 characters\)
sed "s/^X//" >'unix/server/servers.h' <<'END_OF_FILE'
X
X/*
X *  SERVERS.H
X *
X *	DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
X */
X
X#define PORT_FILECOPY	8192
X#define PORT_ALPHATERM	8193
X#define PORT_ECHO	8194
X#define PORT_IALPHATERM 8195
X#define PORT_AMIGATERM	8195
X#define PORT_AMIGASHELL 8196
X#define PORT_LOADAV	8197
X#define PORT_PRINTER	8198
X#define PORT_PASSWD	8199
X#define PORT_BBS	8200
X#define PORT_GFILECOPY	8201
X#define PORT_NFS	8202
X#define PORT_ND		8203
X#define PORT_MAILCHK	8204
X
END_OF_FILE
if test 450 -ne `wc -c <'unix/server/servers.h'`; then
    echo shar: \"'unix/server/servers.h'\" unpacked with wrong size!
fi
# end of 'unix/server/servers.h'
fi
if test -f 'unix/server/smailchk.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unix/server/smailchk.c'\"
else
echo shar: Extracting \"'unix/server/smailchk.c'\" \(10631 characters\)
sed "s/^X//" >'unix/server/smailchk.c' <<'END_OF_FILE'
X
X/*
X *	SMAILCHK.C
X *
X *	DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
X *
X *	Check the mailbox and reports if new mail
X *	has arrived.  Connects to the Mailchk client on the Amiga.
X *	Accepts only one connection.
X *
X *	Written by S. Laroche.
X */
X
X#include <stdio.h>
X#include <sys/time.h>
X#include <sys/file.h>
X#include <errno.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <strings.h>
X#include <sys/param.h>	  /* for definition of MAXPATHLEN */
X
X#include "servers.h"
X
X#define BUFLENGTH		512L
X#define MAILDIR   "/usr/spool/mail/"
X
Xextern int errno;
Xextern char *getenv();
X
Xvoid do_mailchk();
Xchar delmailmsg();
Xchar copyfiles();
Xchar sendmail();
X
Xlong numsecs;
Xchar firstrun;
Xint fd;
X
Xmain(ac,av)
Xchar *av[];
X{
X    long chann = DListen(PORT_MAILCHK);
X    char result;
X
X    if (av[1])
X	chdir(av[1]);
X    signal(SIGALRM, do_mailchk);
X    for (;;) {
X	fd = DAccept(chann);
X	if (fd < 0) {
X	    if (errno == EINTR)
X		continue;
X	    break;
X	}
X	getmailpath();
X	while (ggread(fd,&result,1) == 1) {
X          alarm(0); 
X	  Whatdoyouwant(fd,result);
X          if (result > 1) do_mailchk(); 
X          else alarm(numsecs);
X	}
X	close(fd);
X	_exit(1);
X    }
X    perror("SMAILCHK");
X}
X
Xchar buf[BUFLENGTH], mname[MAXPATHLEN];
X
Xgetmailpath()
X
X{
X    char *buffer;
X
X    if ((buffer = getenv("MAIL")) == NULL) {
X       strcpy(mname,MAILDIR);
X    }
X    else {
X       strcpy(mname,buffer);
X       strcat(mname,"/");
X    }
X    strncat(mname, getenv("USER"), MAXPATHLEN - strlen(mname));
X}
X
XWhatdoyouwant(fd,result)
X
Xint fd;
Xchar result;
X
X/*  This function interprets requests from the Amiga client.
X    0 -> Do nothing
X    1 -> Send the headers of each letter.
X    2 -> Send a particular message.
X    3 -> Delete a particular message.
X    4 -> Initial handshake.
X    5 -> Send mail using "mail".
X*/
X
X{
X    char *buffer;
X    unsigned char dummy;
X    int temp;
X    FILE *fi;
X
X    switch(result) {
X	case 1 :
X	  if (fi = fopen(mname, "r")) {
X	      do {
X		temp = produceheader(fi,buf);
X		if (temp < 0) dummy = strlen(buf);
X		else if (temp == 0) break;
X		     else dummy = temp;
X		gwrite(fd,&dummy,1);
X		gwrite(fd,buf,dummy);
X	      } while (temp > 0);
X	  }
X	  else {
X	    perror("SMAILCHK, error opening mailbox");
X	    exit(0);
X	  }
X	  fclose(fi);
X	  dummy = 0;
X	  gwrite(fd,&dummy,1);
X	  break;
X	case 2 :
X	  buffer = (char *) malloc(BUFLENGTH);
X	  if (buffer == NULL) {
X	      fprintf(stderr,"SMAILCHK:  error allocating memory\n");
X	  }
X	  else {
X	      sendmailmsg(fd,mname,buffer);
X	      free(buffer);
X	  }
X	  break;
X	case 3 :
X	  { char ok;
X
X	  ok = delmailmsg(fd,mname);
X	  gwrite(fd,&ok,1);
X	  }
X	  break;
X	case 4 :
X	  if ((ggread(fd,&numsecs,4)  == 4) &&
X	      (ggread(fd,&firstrun,1) == 1)) {
X               fprintf(stderr,"SMAILCHK, frequency = %ld seconds\n",numsecs);
X               break;
X          }
X	  else { close(fd); _exit(1); }
X        case 5 :
X          { char ok = 0, *address;
X
X	    buffer = (char *) malloc(BUFLENGTH);
X	    address = (char *) malloc(BUFLENGTH);
X	    if ((buffer == NULL) || (address == NULL)) {
X	        fprintf(stderr,"SMAILCHK:  error allocating memory\n");
X	    }
X            else {
X                if (ok = sendmail(fd,address,buffer)) {
X                    sprintf(buf,"mail %s < %s",address,buffer);
X                    ok = system(buf) >> 8;
X                    unlink(buffer);
X                    if (ok == 0) ok = 1;
X                    else ok = 0; 
X                }
X                free(buffer);
X                free(address);
X	    }
X            gwrite(fd,&ok,1);
X            break;
X          }
X    }
X}
X
Xvoid do_mailchk()
X
X{
X    char dummy, *s_mtime;
X    struct stat tempbuf;
X    static char nomail = 1;
X    static long lasttime = 0;
X
X    alarm(numsecs);
X    strcpy(buf,"=");
X    if (stat(mname,&tempbuf) == -1) {
X	if (errno == ENOENT) { if (nomail) {
X				   strcpy(buf,"No mail.");
X				   nomail = 0;
X			       }
X	}
X	else perror("SMAILCHK, Unable to examine file");
X    }
X    else {
X	if (tempbuf.st_mtime >= tempbuf.st_atime) {
X	    s_mtime = ctime(&tempbuf.st_mtime);
X	    strcpy(buf,"New mail arrived on ");
X	    strcat(buf,s_mtime);
X	    nomail = 1;
X	}
X	else if ((firstrun && (tempbuf.st_mtime > lasttime)) ||
X		  firstrun == 2)
X		 strcpy(buf,"You have mail\n");
X	lasttime = tempbuf.st_mtime;
X    }
X    dummy = strlen(buf);
X    if (dummy > 2) {
X	gwrite(fd, &dummy, 1);
X	gwrite(fd, buf, dummy);
X    }
X    firstrun = 1;
X}
X
Xint produceheader(fi,buf)
X
X/* Produce a header of the form 'N sender, date, subject L/C S'
X * where N = number of the message
X *       L = number of lines in message
X *       C = number of characters in message
X *       S = number of characters in message without header
X * 
X * The function returns the # of chars in the header.  When the last
X * header is encountered, the fn returns -(# of chars).
X */
X
XFILE *fi;
Xchar *buf;
X
X{
X    static int mcnt = -1;
X    static char from = 1, subject = 1, Date = 1;
X    static unsigned long llines = 0, lch = 0, sch2, sch1;
X    unsigned long lines, ch;
X    char line[256], fl, *cp;
X    static char date[60], olddate[60], path[80], oldpath[80];
X    static char sub[80], oldsub[80];
X
X    lines = llines;
X    ch = lch;
X    while (cp = fgets(line, 256, fi)) {
X      lines++;
X      ch += strlen(line);
X      llines++;
X      lch += strlen(line);
X      cp[strlen(line)-1] = '\0';
X      if (!strncmp(line, "From ", 5)) {
X	  mcnt++;
X	  from = 0;
X	  subject = 0;
X	  Date = 0;
X	  if (mcnt > 0) {
X	      strcpy(olddate,date);
X	      strcpy(oldpath,path);
X	      strcpy(oldsub,sub);
X	      strcpy(sub,"(no subject)");
X	      strcpy(date,"(no date)"); 
X	      sch2 = sch1;
X	      llines = 1L;
X	      lch = strlen(line) + 1;
X	  }
X      } else
X	  if (!from && ( !strncmp(line, "From: ", 6) ||
X	       !strncmp(line+1, "From: ", 6) )) {
X	      from = 1;
X	      sch1 = ch;
X	      cp = index(line,'<');
X	      if (cp) *cp++;
X	      else cp = index(line,' ')+1;
X	      strcpy(path, cp);
X	      cp = index(path,'>');
X	      if (!cp) cp = index(path,' ');
X	      if (cp) cp[0] = '\0';
X	      if (mcnt > 0) {
X		  fl = 1;
X		  break;
X	      }
X	  } else
X	      if (!subject && !strncmp(line, "Subject: ", 9)) {
X		  subject = 1;
X		  sch1 = ch;
X		  strncpy(sub,index(line,' ')+1,80);
X	      }
X	      else
X		if (!Date && !strncmp(line,"Date: ",6)) {
X		    Date = 1;
X		    sch1 = ch;
X		    cp = index(line,':') + 1;
X		    while (*cp == ' ' || *cp == '\t') *cp++;
X		    strncpy(date,cp,60);
X		}
X      fl = 0;
X    }
X    if (fl) {
X        sprintf(buf," %d %s",mcnt,oldpath);
X        cp = buf + strlen(buf);
X	sprintf(cp,"  %s, %s %ld/%ld %ld \0",olddate,oldsub,lines-llines,ch-lch,sch2);
X    }
X    else {
X        sprintf(buf," %d %s",mcnt+1,path);
X        cp = buf + strlen(buf);
X        sprintf(cp,"  %s, %s %ld/%ld %ld \0",date,sub,lines,ch,sch1);
X    }
X    if (strlen(buf) > 255) buf[254] = '\0';
X    if (fl) return(strlen(buf));
X    else {
X	mcnt = -1;
X        llines = lch = 0L;
X	return(-strlen(buf));
X    }
X}
X
Xsendmailmsg(fd,mname,buffer)
X
Xchar *buffer, *mname;
Xint fd;
X
X{
X  long len= BUFLENGTH;
X  unsigned long nochars, stchar;
X  char dummy;
X  FILE *fi;
X
X  if (ggread(fd,&stchar,4) == 4) {
X      if (ggread(fd,&nochars,4) == 4) {
X	  if (fi = fopen(mname,"r")) {
X	      if (fseek(fi,stchar,0) < 0) {
X		  fclose(fi);
X		  exit;
X	      }
X	      else {
X		  dummy = 0;
X		  while (nochars > len) {
X			 fread(buffer,1,len,fi);
X			 nochars -= len;
X			 gwrite(fd,&len,4);
X			 gwrite(fd,buffer,len);
X			 ggread(fd,&dummy,1);
X			 if (dummy) break;
X			}
X		  if (dummy == 0) {
X		      if (fread(buffer,1,nochars,fi) != nochars) {
X			  perror("SMAILCHK, unable to read mail file");
X			  exit;
X		      }
X		      gwrite(fd,&nochars,4);
X		      gwrite(fd,buffer,nochars);
X		      ggread(fd,&dummy,1);
X		      nochars = 0L;
X		      gwrite(fd,&nochars,4);
X		  }
X	      }
X	      fclose(fi);
X	   }
X       }
X   }
X}
X
Xchar sendmail(fd,address,fname)
X
Xint fd;
Xchar *address, *fname;
X
X{
X  FILE *fi;
X  char ok = 0, *tname;
X
X  if (!(tname = getenv("DNETDIR"))) return(ok);
X  sprintf(fname,"%smailchk%ld",tname,getpid());
X  {  short len;
X     if (ggread(fd,&len,2) != 2) return(ok);
X     if (ggread(fd,address,len) != len) return(ok);
X  }
X  {  long len;
X     if (ggread(fd,&len,4) != 4) return(ok);
X     if ((fi = fopen(fname, "w")) == NULL) return(ok);
X     while (len > BUFLENGTH) {
X         int count = BUFLENGTH;
X         if (ggread(fd,buf,count) != count) goto fin;
X         if (fwrite(buf,1,count,fi) != count) {
X             perror("SMAILCHK, error while writing");
X             goto fin;
X         }
X         len -= count;
X     }
X     if (len > 0) {
X         if (ggread(fd,buf,len) != len) goto fin;
X         if (fwrite(buf,1,len,fi) != len) {
X             perror("SMAILCHK, error while writing");
X             goto fin; 
X         }
X     }
X     ok = 1;
Xfin: fclose(fi);
X     if (!ok) unlink(fname);
X     return(ok);
X  }
X}
X
Xchar delmailmsg(fd,mname)
X
Xchar *mname;
Xint fd;
X
X{
X  long nochars, stchar;
X  FILE *f1, *f2;
X  char ok = 0, *tname;
X
X
X  if (!(tname = getenv("DNETDIR"))) return(ok);
X  strcpy(buf,tname);
X  strcat(buf,"MAIL0001");
X  if (ggread(fd,&stchar,4) == 4)
X      if (ggread(fd,&nochars,4) == 4)
X	  if ((f1 = fopen(mname,"r")) && (f2 = fopen(buf,"w+"))) {
X	      if (copyfiles(f1,f2,stchar))
X		  if (fseek(f1,nochars,1) == 0)
X		      if (ok = copyfiles(f1,f2,-1)) {
X			  fclose(f1);
X			  if (unlink(mname) < 0) {
X			      perror("SMAILCHK, Error while removing");
X			      fclose(f2);
X			      unlink(buf);
X			      return(0);
X			  }
X			  rewind(f2);
X			  if (f1 = fopen(mname,"w")) {
X			      fchmod(f1,0600);
X			      ok = copyfiles(f2,f1,-1);
X			      fclose(f1);
X			      fclose(f2);
X			      unlink(buf);
X			  }
X			  else {
X			      perror("SMAILCHK, Error writing in spool dir");
X			      fclose(f2);
X			      return(0);
X			  }
X			  if (f1 = fopen(mname,"r")) { /* Touch the file */
X			      char f = 0;
X			      fread(f,1,1,f1);
X			      fseek(f1,0,2);
X			      if (ftell(f1) < 2) f = 1;
X			      fclose(f1);
X			      if (f) unlink(mname);
X			  }
X			  return(ok);
X		      }
X	      perror("SMAILCHK, Error while writing");
X	      fclose(f1);
X	      fclose(f2);
X	      return(0);
X	  }
X  perror("SMAILCHK, Delete operation");
X  return(0);
X}
X
Xchar copyfiles(f1,f2,n)
X
XFILE *f1, *f2;
Xlong n;
X
X{
X  char buffer[1024], ok = 1;
X  int tmp;
X
X  while (n > 1024 || n < 0) {
X    if (n > 0) n -= 1024;
X    if ((tmp = fread(buffer,1,1024,f1)) == 1024)
X	if (fwrite(buffer,1,1024,f2) == 1024)
X	    continue;
X    ok = 0;
X    break;
X  }
X  while (ok && n > 0) {
X      if (fread(buffer,1,n,f1) == n)
X	  if (fwrite(buffer,1,n,f2) == n)
X	      break;
X      ok = 0;
X  }
X  if (n >= 0) return(ok);
X  if (fwrite(buffer,1,tmp,f2) == tmp) ok = 1;
X  return(ok);
X}
END_OF_FILE
if test 10631 -ne `wc -c <'unix/server/smailchk.c'`; then
    echo shar: \"'unix/server/smailchk.c'\" unpacked with wrong size!
fi
# end of 'unix/server/smailchk.c'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.
