Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (07/03/90)
Submitted-by: <lobster@quiche.cs.mcgill.ca> Posting-number: Volume 90, Issue 193 Archive-name: comm/dnet/mailchk-05/part02 #!/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 2 (of 3)." # Contents: amiga/client/mailchk.c # Wrapped by tadguy@xanth on Mon Jul 2 19:53:59 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH 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'\" \(23145 characters\) sed "s/^X//" >'amiga/client/mailchk.c' <<'END_OF_FILE' 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 * April 19, 1990 X * X * Usage: mailchk [-N(host) -s(flag) -w(flag) -t(time) -q X * -h: Help message X * -s: flag=0: Don't talk; otherwise talk X * -w: flag=0: No window; other open a window X * -t: (time) is the number of seconds between checks. X * Default: 40 seconds X * -q: Remove mailchk 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" /* menu definitions */ X X/* Icon images */ X#define YOUHAVEMAIL 0 X#define NEWMAIL 1 X#define NOMAIL 2 X X/* Server commands */ X#define GETNEWMAIL 1 X#define GETMAILMSG 2 X#define DELMAILMSG 3 X#define INITSERVER 4 X#define EDITMESSAGE 5 X X/* For use with Matt Dillon's config utility */ Xshort Deemu[] = { X DMSTRT, 0, 0, X DMNW , 0, 4, 0, 10, X/* DMNW , 0, 10, 2, 2, -80, 40, 0xFFFF, */ X DMEND , 0, 0 X}; X X#define DMICONNWOFF 4 X/* #define DMNWOFF 14 */ X X/* Buffer lengths */ X#define MAILLENGTH 256 /* Max. number of characters in 1 msg header */ X#define BUFLENGTH 512 /* Length of buffer used for communication */ X X/* Intuition shortcuts */ X#define MENUSTRIP(n) (SHIFTMENU(n)|SHIFTITEM(NOITEM)) X#define BUSYPOINTER(n) (SetPointer(n, BusyPointer, 22, 16, 0, 0)) X#define IDCMPFLAGS NEWSIZE|MENUPICK|CLOSEWINDOW|MOUSEBUTTONS X X/* Storage defined in mailchk_chip.c */ Xextern USHORT BusyPointer[]; /* Busy pointer image */ Xextern struct Image MbImage; /* Mailbox icon */ Xextern USHORT MbBitMap[3][48*36]; /* Images for mailbox icon */ X X/* Globals */ Xubyte Title[128]; /* Window title */ Xubyte MailVersion[80]; /* Version number, formatted for Title */ X X/* Windows and gadgets */ XNW Nw = { X 0, 20, 640, 100, -1, -1, X NULL, X WINSTD|NOCAREREFRESH, X NULL, NULL, Title, NULL, NULL, X 32, 18, -1, -1, WBENCHSCREEN X}; /* Headers window */ X Xstatic struct Gadget gadget = /* Used to display the mailbox */ X{ NULL, X 0, 0, 0, 0, X GADGHNONE|GRELWIDTH|GRELHEIGHT|GADGIMAGE, X GADGIMMEDIATE|RELVERIFY, X WDRAGGING, X (APTR) &MbImage, X NULL, X NULL, X NULL, X NULL, X 0, 0 X}; /* Mailbox icon */ X Xstatic NW IconNW = /* The mailbox window */ X{ 0, 11, X 48, 36, X -1, -1, X GADGETDOWN|MENUPICK, X BORDERLESS|SMART_REFRESH|NOCAREREFRESH, X &gadget, X NULL, X NULL, X NULL, X NULL, X 0, 0, 0, 0, X WBENCHSCREEN X}; /* Window for icon */ X X/* linked lists of headers */ Xstruct MailMsg { X char msg[MAILLENGTH]; X struct MailMsg *next; X}; X Xstruct MailMsg *MailP=NULL; /* 1st pointer of linked list */ XUSHORT NumMsg = 0; /* Number of messages in linked list */ X X/* Message struct to communicate between two running mailchk */ Xstruct mailmsg { X struct Message ml_msg; X unsigned long secs; X BYTE quit, speak, win; X}; X X XWIN *Win = NULL, *MbWin = NULL; XRP *Rp; X Xchar DefaultSpeaker[] = "SPEAK:"; /* Used when env. var. SPEAKER isn't set */ 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) X Xchar *av[]; X X{ X long chan = NULL; X unsigned long numsecs = 0L; X BYTE firstrun = 1, quit = 0; X char *host = NULL; X int i; X X ArpBase = (long)OpenLibrary(ArpName,39L); X if (ArpBase == NULL) exit(1); X X if (!param(ac,av,&numsecs,&quit,&host)) { X CloseLibrary(ArpBase); X exit(0); X } X { X char buf[64]; X PORT *pr; X X sprintf(MailVersion, "MailChkV%s%s ", VERSION, MAILCHK_VERSION); X strncpy(buf,MailVersion,7); X buf[7] = '\0'; X strcat(MailVersion, " - April 25 1990"); 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 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 InitDeemuNW(Deemu+DMICONNWOFF, &IconNW); X if ((MbWin = OpenWindow(&IconNW)) == NULL) goto fail; X refreshmenu(); X SetMenuStrip(MbWin,Menu); X OffMenu(MbWin,MENUSTRIP(1)); X if (initmailserver(chan,numsecs,firstrun)) X checkmail(chan,numsecs); X Xfail: X if (Win) X CloseWinSafely(Win); X if (MbWin) X CloseWindow(MbWin); 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,quit,host) X Xchar *av[]; XBYTE *quit; Xunsigned long *numsecs; XULONG *host; X X{ X register short i; X for (i = 1; i < ac; ++i) { 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 continue; X } X if (strncmp(av[i],"-n",2) == 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 if (strncmp(av[i],"-h",2) != 0) { X Printf("Illegal switch: %s\n",av[i]); X } X Printf("DNET - (C) Matthew Dillon 1988\n"); X Printf("%s\n",MailVersion); X Printf("\nUsage: run mailchk [-N(host) -t(time) -s(flag) -w(flag) q|h]\n"); X Printf(" -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(" -q Remove the MailChk client, if it is running\n"); X Printf(" -h This message...\n"); X return(0); X } X return(1); X} X Xinitmailserver(chan,numsecs,firstrun) X Xlong chan, numsecs; Xchar firstrun; X X{ X char init = INITSERVER; 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, dmask, omask, mask; X char notdone = 1, nowindow = 0; X ULONG prsec = 0, prmic = 0, prsec2 = 0, prmic2 = 0; X BYTE pos = 0, oldpos = 0; X X dmask = 1 << ((PORT *) chan)->mp_SigBit; X omask = 1 << MailPort->mp_SigBit; X imask = 1 << MbWin->UserPort->mp_SigBit; X while (notdone) { X if (Win) { X OnMenu(Win,MENUSTRIP(0)); X OnMenu(Win,MENUSTRIP(1)); X } X OnMenu(MbWin,MENUSTRIP(0)); X mask = Wait(imask|dmask|omask|SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_E); X OffMenu(MbWin,MENUSTRIP(0)); 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 if (msg->secs > 0) X initmailserver(chan,numsecs,2); X ReplyMsg(msg); 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(MbWin->UserPort)) { X class = im->Class; X switch(class) { X case GADGETDOWN: X if (im->IDCMPWindow != MbWin || NumMsg == 0) { X ReplyMsg(im); X break; X } X if (DoubleClick(prsec2,prmic2,im->Seconds,im->Micros)) { X ReplyMsg(im); X if (Win) { X WindowToFront(Win); X break; X } X else if (WindowPlease) { X Win = OpenWindow(&Nw); X if (Win != NULL) { X Rp = Win->RPort; X Win->UserPort = MbWin->UserPort; X ModifyIDCMP(Win,IDCMPFLAGS); X refreshmenu(); X SetMenuStrip(Win,Menu); X OffMenu(Win,MENUSTRIP(0)); X OffMenu(Win,MENUSTRIP(1)); X } X } X newimage(YOUHAVEMAIL); X if (NumMsg == 65535) getnewmail(chan); X else { X strcpy(Title,MailVersion); X dispnewmail(0,0,1); X } X } X else { X prsec2 = im->Seconds; X prmic2 = im->Micros; X ReplyMsg(im); X } X break; 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 0x0000: /* Talk */ X SpeakPlease = 1 - SpeakPlease; X break; X case 0x0001: /* Window */ X WindowPlease = 1 - WindowPlease; X break; X case 0x0002: /* Remove */ X notdone = 0; X break; X } X } X if (class != MENUPICK && class != GADGETDOWN) ReplyMsg(im); X } X } X if (mask & dmask) { X char len = 0; X short temp = 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) { X nowindow = 1; X freemail(MailP); X newimage(NOMAIL); X } X else { if (strncmp(Title,"New mail",8) == 0) { X DisplayBeep(NULL); X newimage(NEWMAIL); X Delay(50); X DisplayBeep(NULL); X } X else newimage(YOUHAVEMAIL); 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 NumMsg = -1; X if (Win) { X WindowToFront(Win); X getnewmail(chan); X newimage(YOUHAVEMAIL); X } X if (!SpeakPlease && !WindowPlease) { X Puts(Title); X getnewmail(chan); 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 CloseWinSafely(Win); X Win = NULL; X } X nowindow = 0; X } X X freemail(MailP); X if (Win) { X ClearMenuStrip(Win); X CloseWinSafely(Win); X Win = NULL; X } X} X X/* X * Utility routines. ************************************************ X */ X Xrefreshmenu() X X/* Refresh the two toggle menus(Talk, Window) in the Project strip X * according to the flags SpeakPlease and WindowPlease. X */ X X{ X struct MenuItem *mn_ad; X X mn_ad = (struct MenuItem *) ItemAddress(Menu,SHIFTMENU(0)|SHIFTITEM(0)); X if (SpeakPlease) mn_ad->Flags |= CHECKED; X else mn_ad->Flags &= ~(CHECKED); X mn_ad = (struct MenuItem *) ItemAddress(Menu,SHIFTMENU(0)|SHIFTITEM(1)); X if (WindowPlease) mn_ad->Flags |= CHECKED; X else mn_ad->Flags &= ~(CHECKED); X} X Xnewimage(index) X X/* Change the mailbox icon. X * Values of index: X * 0 -> "You have mail", 1-> "New mail", 2-> "No mail" X */ X X{ X MbImage.ImageData = &MbBitMap[index][0]; X RefreshGList(&gadget,MbWin,NULL,1); X} X X Xgetnewmail(chan) X Xlong chan; X X/* Get all messages (headers only) from the host. X * It will also display thoses headers using dispnewmail(). X * The magic number 1 is used to tell the server what we want. X */ X X{ X unsigned char len = GETNEWMAIL; X struct MailMsg *p; X register USHORT count = 0; X X if (Win) { X BUSYPOINTER(Win); X SetWindowTitles(Win,MailVersion,-1); 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 NumMsg = count; X if (Win) ClearPointer(Win); X dispnewmail(0,0,1); X} X Xdispnewmail(ONmsgno,OFFmsgno,flag) X XBYTE ONmsgno, OFFmsgno, flag; X X/* Display mail headers in a window if one is opened or on stdout otherwise. X * ONmsgno : msg no to be output in reverse ( 0 = none) X * OFFmsgno: msg no to be output normally. X * flag : 1 -> It's a new window, 0 -> it's an old window X */ 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 char buf[25], buf2[9]; X X SetAPen(Rp, 0); X RectFill(Rp, WOx, WOy, Ww + WOx, Wh + WOy); X WindowToFront(Win); X strcpy(buf2,"message"); X if (NumMsg > 1) strcat(buf2,"s"); X sprintf(buf," (%d %s)",NumMsg,buf2); X if (Title[strlen(Title)-1] != ')') strcat(Title,buf); X SetWindowTitles(Win, Title, -1); 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/* Send a command to the server asking it to delete message number msgno. X */ X X{ X register BYTE i=1; X struct MailMsg *p = MailP; X char dummy[32]; X BYTE dl = DELMAILMSG, ok; X unsigned long stchar = 0,nochars; X X BUSYPOINTER(Win); 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) strcpy(Title,"Delete successful "); X else strcpy(Title,"Delete error "); X getnewmail(chan); X } X ClearPointer(Win); X} X Xint getmailmsg(chan,msgno,flag) X Xlong chan; XBYTE msgno, flag; X X/* Get message number msgno from the host and take the following action X * according to the value of flag: X * X * 0 -> View the message on screen (using more or the env var PAGER) X * 1 -> Print the message on PRT: X * 2 -> Save the message in a file. X * 3 -> Send the message to the SPEAK: device (without the headers) X */ X X{ X struct MailMsg *p = MailP; X BYTE i, ok=0, hd = GETMAILMSG, l, start = 0; X unsigned long stchar=0L, nochars, len; X struct FileHandle *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: /* View */ 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: /* Print */ X strcpy(vname,"PRT:"); X strcpy(title,"Printing "); X break; X case 2: /* Save */ 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: /* Speak */ 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 BUSYPOINTER(Win); 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 ClearPointer(Win); X return(rcode); X} X Xint editmessage(chan,msgno) X Xlong *chan; XUBYTE msgno; X X/* Reply to message number msgno using ed or the env var EDITOR. X * A temporary file in the T: directory is used. X * X * Still buggy for unknown reasons. X */ 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 = EDITMESSAGE, 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 BUSYPOINTER(Win); 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 ClearPointer(Win); 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/* Extract the no of chars (nochars) from a particular header (pointed to X * by p) in the message and the no of chars without the header lines X * (len). X */ 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/* Free all the memory used by the linked list X */ X X{ X while (p != NULL) { X FreeMem(p,sizeof(*p)); X p = p->next; X } X MailP = NULL; X NumMsg = 0; X} X XCloseWinSafely(win) X XWIN *win; X X/* From RKM 1.3. X * Close window win safely when it shares an IDCMP port with other X * windows. X */ X X{ X Forbid(); X StripIntuiMessages(win->UserPort,win); X win->UserPort = NULL; X ModifyIDCMP(win,0); X Permit(); X CloseWindow(win); X} X XStripIntuiMessages(mp,win) X XPORT *mp; XWIN *win; X X/* From RKM 1.3 */ X X{ X IMESS *msg, *succ; X X msg = (IMESS *) mp->mp_MsgList.lh_Head; X while (succ = (IMESS *) msg->ExecMessage.mn_Node.ln_Succ) { X if (msg->IDCMPWindow == win) { X Remove(msg); X ReplyMsg(msg); X } X msg = succ; X } X} X END_OF_FILE if test 23145 -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 echo shar: End of archive 2 \(of 3\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 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.
Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (07/03/90)
Submitted-by: <lobster@quiche.cs.mcgill.ca> Posting-number: Volume 90, Issue 193 Archive-name: comm/dnet/mailchk-05/part02 #!/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 2 (of 3)." # Contents: amiga/client/mailchk.c # Wrapped by tadguy@xanth on Tue Jul 3 08:56:46 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH 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'\" \(23145 characters\) sed "s/^X//" >'amiga/client/mailchk.c' <<'END_OF_FILE' 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 * April 19, 1990 X * X * Usage: mailchk [-N(host) -s(flag) -w(flag) -t(time) -q X * -h: Help message X * -s: flag=0: Don't talk; otherwise talk X * -w: flag=0: No window; other open a window X * -t: (time) is the number of seconds between checks. X * Default: 40 seconds X * -q: Remove mailchk 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" /* menu definitions */ X X/* Icon images */ X#define YOUHAVEMAIL 0 X#define NEWMAIL 1 X#define NOMAIL 2 X X/* Server commands */ X#define GETNEWMAIL 1 X#define GETMAILMSG 2 X#define DELMAILMSG 3 X#define INITSERVER 4 X#define EDITMESSAGE 5 X X/* For use with Matt Dillon's config utility */ Xshort Deemu[] = { X DMSTRT, 0, 0, X DMNW , 0, 4, 0, 10, X/* DMNW , 0, 10, 2, 2, -80, 40, 0xFFFF, */ X DMEND , 0, 0 X}; X X#define DMICONNWOFF 4 X/* #define DMNWOFF 14 */ X X/* Buffer lengths */ X#define MAILLENGTH 256 /* Max. number of characters in 1 msg header */ X#define BUFLENGTH 512 /* Length of buffer used for communication */ X X/* Intuition shortcuts */ X#define MENUSTRIP(n) (SHIFTMENU(n)|SHIFTITEM(NOITEM)) X#define BUSYPOINTER(n) (SetPointer(n, BusyPointer, 22, 16, 0, 0)) X#define IDCMPFLAGS NEWSIZE|MENUPICK|CLOSEWINDOW|MOUSEBUTTONS X X/* Storage defined in mailchk_chip.c */ Xextern USHORT BusyPointer[]; /* Busy pointer image */ Xextern struct Image MbImage; /* Mailbox icon */ Xextern USHORT MbBitMap[3][48*36]; /* Images for mailbox icon */ X X/* Globals */ Xubyte Title[128]; /* Window title */ Xubyte MailVersion[80]; /* Version number, formatted for Title */ X X/* Windows and gadgets */ XNW Nw = { X 0, 20, 640, 100, -1, -1, X NULL, X WINSTD|NOCAREREFRESH, X NULL, NULL, Title, NULL, NULL, X 32, 18, -1, -1, WBENCHSCREEN X}; /* Headers window */ X Xstatic struct Gadget gadget = /* Used to display the mailbox */ X{ NULL, X 0, 0, 0, 0, X GADGHNONE|GRELWIDTH|GRELHEIGHT|GADGIMAGE, X GADGIMMEDIATE|RELVERIFY, X WDRAGGING, X (APTR) &MbImage, X NULL, X NULL, X NULL, X NULL, X 0, 0 X}; /* Mailbox icon */ X Xstatic NW IconNW = /* The mailbox window */ X{ 0, 11, X 48, 36, X -1, -1, X GADGETDOWN|MENUPICK, X BORDERLESS|SMART_REFRESH|NOCAREREFRESH, X &gadget, X NULL, X NULL, X NULL, X NULL, X 0, 0, 0, 0, X WBENCHSCREEN X}; /* Window for icon */ X X/* linked lists of headers */ Xstruct MailMsg { X char msg[MAILLENGTH]; X struct MailMsg *next; X}; X Xstruct MailMsg *MailP=NULL; /* 1st pointer of linked list */ XUSHORT NumMsg = 0; /* Number of messages in linked list */ X X/* Message struct to communicate between two running mailchk */ Xstruct mailmsg { X struct Message ml_msg; X unsigned long secs; X BYTE quit, speak, win; X}; X X XWIN *Win = NULL, *MbWin = NULL; XRP *Rp; X Xchar DefaultSpeaker[] = "SPEAK:"; /* Used when env. var. SPEAKER isn't set */ 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) X Xchar *av[]; X X{ X long chan = NULL; X unsigned long numsecs = 0L; X BYTE firstrun = 1, quit = 0; X char *host = NULL; X int i; X X ArpBase = (long)OpenLibrary(ArpName,39L); X if (ArpBase == NULL) exit(1); X X if (!param(ac,av,&numsecs,&quit,&host)) { X CloseLibrary(ArpBase); X exit(0); X } X { X char buf[64]; X PORT *pr; X X sprintf(MailVersion, "MailChkV%s%s ", VERSION, MAILCHK_VERSION); X strncpy(buf,MailVersion,7); X buf[7] = '\0'; X strcat(MailVersion, " - April 25 1990"); 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 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 InitDeemuNW(Deemu+DMICONNWOFF, &IconNW); X if ((MbWin = OpenWindow(&IconNW)) == NULL) goto fail; X refreshmenu(); X SetMenuStrip(MbWin,Menu); X OffMenu(MbWin,MENUSTRIP(1)); X if (initmailserver(chan,numsecs,firstrun)) X checkmail(chan,numsecs); X Xfail: X if (Win) X CloseWinSafely(Win); X if (MbWin) X CloseWindow(MbWin); 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,quit,host) X Xchar *av[]; XBYTE *quit; Xunsigned long *numsecs; XULONG *host; X X{ X register short i; X for (i = 1; i < ac; ++i) { 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 continue; X } X if (strncmp(av[i],"-n",2) == 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 if (strncmp(av[i],"-h",2) != 0) { X Printf("Illegal switch: %s\n",av[i]); X } X Printf("DNET - (C) Matthew Dillon 1988\n"); X Printf("%s\n",MailVersion); X Printf("\nUsage: run mailchk [-N(host) -t(time) -s(flag) -w(flag) q|h]\n"); X Printf(" -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(" -q Remove the MailChk client, if it is running\n"); X Printf(" -h This message...\n"); X return(0); X } X return(1); X} X Xinitmailserver(chan,numsecs,firstrun) X Xlong chan, numsecs; Xchar firstrun; X X{ X char init = INITSERVER; 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, dmask, omask, mask; X char notdone = 1, nowindow = 0; X ULONG prsec = 0, prmic = 0, prsec2 = 0, prmic2 = 0; X BYTE pos = 0, oldpos = 0; X X dmask = 1 << ((PORT *) chan)->mp_SigBit; X omask = 1 << MailPort->mp_SigBit; X imask = 1 << MbWin->UserPort->mp_SigBit; X while (notdone) { X if (Win) { X OnMenu(Win,MENUSTRIP(0)); X OnMenu(Win,MENUSTRIP(1)); X } X OnMenu(MbWin,MENUSTRIP(0)); X mask = Wait(imask|dmask|omask|SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_E); X OffMenu(MbWin,MENUSTRIP(0)); 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 if (msg->secs > 0) X initmailserver(chan,numsecs,2); X ReplyMsg(msg); 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(MbWin->UserPort)) { X class = im->Class; X switch(class) { X case GADGETDOWN: X if (im->IDCMPWindow != MbWin || NumMsg == 0) { X ReplyMsg(im); X break; X } X if (DoubleClick(prsec2,prmic2,im->Seconds,im->Micros)) { X ReplyMsg(im); X if (Win) { X WindowToFront(Win); X break; X } X else if (WindowPlease) { X Win = OpenWindow(&Nw); X if (Win != NULL) { X Rp = Win->RPort; X Win->UserPort = MbWin->UserPort; X ModifyIDCMP(Win,IDCMPFLAGS); X refreshmenu(); X SetMenuStrip(Win,Menu); X OffMenu(Win,MENUSTRIP(0)); X OffMenu(Win,MENUSTRIP(1)); X } X } X newimage(YOUHAVEMAIL); X if (NumMsg == 65535) getnewmail(chan); X else { X strcpy(Title,MailVersion); X dispnewmail(0,0,1); X } X } X else { X prsec2 = im->Seconds; X prmic2 = im->Micros; X ReplyMsg(im); X } X break; 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 0x0000: /* Talk */ X SpeakPlease = 1 - SpeakPlease; X break; X case 0x0001: /* Window */ X WindowPlease = 1 - WindowPlease; X break; X case 0x0002: /* Remove */ X notdone = 0; X break; X } X } X if (class != MENUPICK && class != GADGETDOWN) ReplyMsg(im); X } X } X if (mask & dmask) { X char len = 0; X short temp = 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) { X nowindow = 1; X freemail(MailP); X newimage(NOMAIL); X } X else { if (strncmp(Title,"New mail",8) == 0) { X DisplayBeep(NULL); X newimage(NEWMAIL); X Delay(50); X DisplayBeep(NULL); X } X else newimage(YOUHAVEMAIL); 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 NumMsg = -1; X if (Win) { X WindowToFront(Win); X getnewmail(chan); X newimage(YOUHAVEMAIL); X } X if (!SpeakPlease && !WindowPlease) { X Puts(Title); X getnewmail(chan); 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 CloseWinSafely(Win); X Win = NULL; X } X nowindow = 0; X } X X freemail(MailP); X if (Win) { X ClearMenuStrip(Win); X CloseWinSafely(Win); X Win = NULL; X } X} X X/* X * Utility routines. ************************************************ X */ X Xrefreshmenu() X X/* Refresh the two toggle menus(Talk, Window) in the Project strip X * according to the flags SpeakPlease and WindowPlease. X */ X X{ X struct MenuItem *mn_ad; X X mn_ad = (struct MenuItem *) ItemAddress(Menu,SHIFTMENU(0)|SHIFTITEM(0)); X if (SpeakPlease) mn_ad->Flags |= CHECKED; X else mn_ad->Flags &= ~(CHECKED); X mn_ad = (struct MenuItem *) ItemAddress(Menu,SHIFTMENU(0)|SHIFTITEM(1)); X if (WindowPlease) mn_ad->Flags |= CHECKED; X else mn_ad->Flags &= ~(CHECKED); X} X Xnewimage(index) X X/* Change the mailbox icon. X * Values of index: X * 0 -> "You have mail", 1-> "New mail", 2-> "No mail" X */ X X{ X MbImage.ImageData = &MbBitMap[index][0]; X RefreshGList(&gadget,MbWin,NULL,1); X} X X Xgetnewmail(chan) X Xlong chan; X X/* Get all messages (headers only) from the host. X * It will also display thoses headers using dispnewmail(). X * The magic number 1 is used to tell the server what we want. X */ X X{ X unsigned char len = GETNEWMAIL; X struct MailMsg *p; X register USHORT count = 0; X X if (Win) { X BUSYPOINTER(Win); X SetWindowTitles(Win,MailVersion,-1); 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 NumMsg = count; X if (Win) ClearPointer(Win); X dispnewmail(0,0,1); X} X Xdispnewmail(ONmsgno,OFFmsgno,flag) X XBYTE ONmsgno, OFFmsgno, flag; X X/* Display mail headers in a window if one is opened or on stdout otherwise. X * ONmsgno : msg no to be output in reverse ( 0 = none) X * OFFmsgno: msg no to be output normally. X * flag : 1 -> It's a new window, 0 -> it's an old window X */ 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 char buf[25], buf2[9]; X X SetAPen(Rp, 0); X RectFill(Rp, WOx, WOy, Ww + WOx, Wh + WOy); X WindowToFront(Win); X strcpy(buf2,"message"); X if (NumMsg > 1) strcat(buf2,"s"); X sprintf(buf," (%d %s)",NumMsg,buf2); X if (Title[strlen(Title)-1] != ')') strcat(Title,buf); X SetWindowTitles(Win, Title, -1); 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/* Send a command to the server asking it to delete message number msgno. X */ X X{ X register BYTE i=1; X struct MailMsg *p = MailP; X char dummy[32]; X BYTE dl = DELMAILMSG, ok; X unsigned long stchar = 0,nochars; X X BUSYPOINTER(Win); 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) strcpy(Title,"Delete successful "); X else strcpy(Title,"Delete error "); X getnewmail(chan); X } X ClearPointer(Win); X} X Xint getmailmsg(chan,msgno,flag) X Xlong chan; XBYTE msgno, flag; X X/* Get message number msgno from the host and take the following action X * according to the value of flag: X * X * 0 -> View the message on screen (using more or the env var PAGER) X * 1 -> Print the message on PRT: X * 2 -> Save the message in a file. X * 3 -> Send the message to the SPEAK: device (without the headers) X */ X X{ X struct MailMsg *p = MailP; X BYTE i, ok=0, hd = GETMAILMSG, l, start = 0; X unsigned long stchar=0L, nochars, len; X struct FileHandle *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: /* View */ 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: /* Print */ X strcpy(vname,"PRT:"); X strcpy(title,"Printing "); X break; X case 2: /* Save */ 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: /* Speak */ 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 BUSYPOINTER(Win); 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 ClearPointer(Win); X return(rcode); X} X Xint editmessage(chan,msgno) X Xlong *chan; XUBYTE msgno; X X/* Reply to message number msgno using ed or the env var EDITOR. X * A temporary file in the T: directory is used. X * X * Still buggy for unknown reasons. X */ 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 = EDITMESSAGE, 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 BUSYPOINTER(Win); 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 ClearPointer(Win); 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/* Extract the no of chars (nochars) from a particular header (pointed to X * by p) in the message and the no of chars without the header lines X * (len). X */ 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/* Free all the memory used by the linked list X */ X X{ X while (p != NULL) { X FreeMem(p,sizeof(*p)); X p = p->next; X } X MailP = NULL; X NumMsg = 0; X} X XCloseWinSafely(win) X XWIN *win; X X/* From RKM 1.3. X * Close window win safely when it shares an IDCMP port with other X * windows. X */ X X{ X Forbid(); X StripIntuiMessages(win->UserPort,win); X win->UserPort = NULL; X ModifyIDCMP(win,0); X Permit(); X CloseWindow(win); X} X XStripIntuiMessages(mp,win) X XPORT *mp; XWIN *win; X X/* From RKM 1.3 */ X X{ X IMESS *msg, *succ; X X msg = (IMESS *) mp->mp_MsgList.lh_Head; X while (succ = (IMESS *) msg->ExecMessage.mn_Node.ln_Succ) { X if (msg->IDCMPWindow == win) { X Remove(msg); X ReplyMsg(msg); X } X msg = succ; X } X} X END_OF_FILE if test 23145 -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 echo shar: End of archive 2 \(of 3\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 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.