SRI-NOSC/mmdf/netsnd.c

Compare this file to the similar file:
Show the results in this format:

#
/*
 *   MULTI-CHANNEL MEMO DISTRIBUTION FACILITY (MMDF)
 *
 *   Copyright (C) 1979  University of Delaware
 *
 *   This program and its listings may be copied freely by United States
 *   federal, state, and local government agencies and by not-for-profit
 *   institutions, after sending written notification to:
 *
 *      Professor David J. Farber
 *      Department of Electrical Engineering
 *      University of Delaware
 *      Newark, Delaware  19711
 *
 *          Telephone:  (302) 738-2405
 *
 *  Notification should include the name of the acquiring organization,
 *  name and contact information for the person responsible for maintaining
 *  the operating system, and license information if MMDF will be run on a
 *  Western Electric Unix(TM) operating system.
 *
 *  Others may obtain copies by arrangement.
 *
 *  The system was originally implemented by David H. Crocker, and the
 *  effort was supported in part by the University of Delaware and in part
 *  by contracts from the United States Department of the Army Readiness
 *  and Materiel Command and the General Systems Division of International
 *  Business Machines.  The system was built upon software initially
 *  developed by The Rand Corporation, under the sponsorship of the
 *  Information Processing Techniques Office of the Defense Advanced
 *  Research Projects Agency, and was developed with their cooperation.
 *
 *  The above statements must be retained with all copies of this program
 *  and may not be removed without the consent of the University of
 *  Delaware.
 **/
#include "mailer.h"
#include "open.h"
#define MLFL

struct iobuf tnibuf, tnobuf;
struct netstruct net_arpa;
int domsg;
char errline[ERRLINSIZ + 1];
int savenv;
int infd;
int tnfd;
int tnfd1;
int filesiz;
char *txtname;
char *hostnam;
struct adr adr;

main(argc,argv)
int argc;
char *argv[];

{
register char *p;
register int c;
int result;
char *name;
int host;

signal (SIGINR, 1);
openparam.o_fskt[1] = 3;
openparam.o_timo = 60;
initcom (argc, argv);

for EVER
{
switch (getname ())
{
case NOTOK:
sysabrt (HOSTDEAD);
case DONE:
putresp (0, 0);
if ((c = newfile ()) != OK)
sysabrt (c);
continue;
}
for (p = adr.adr_name; *p && *p != '\n'; p++);
*p = '\0';

domsg = (adr.adr_hand == 'w');

seek (infd, 0, 0);
result = send();
putresp (result, (result == OK) ? 0 : errline);
}
}


opnnet (hostnum)
int hostnum;
{
static int result;
static int curhost;
int code;

if (tnfd)
{ if (hostnum == curhost)
return(OK);
clsnet (1);
}
else
{ if (hostnum == curhost)
return(result);
}
curhost = hostnum;
openparam.o_host = hostnum;
printx ("connecting... ");
log ("[ %s ]", hostnam);
if ((tnfd = open ("/dev/net/anyhost", &openparam)) < 0)
{
log ("Can't connect");
tnfd = 0;
result = HOSTDEAD;
}
else
{ zero (&tnibuf, sizeof tnibuf);
zero (&tnobuf, sizeof tnobuf);
tnibuf.fildes = tnobuf.fildes = tnfd;
tnfd1 = dup (tnfd);

if (envsave (&savenv))
{
alarm (30);
while ((code = getcode ()) != 300 && code >= 0);
alarm (0);
result = (code < 0 ? BADNET : OK);
}
else
result = TIMEOUT;

if (result != OK)
{
close (tnfd);
close (tnfd1);
tnfd = 0;
}
}
return (result);
}


clsnet (flag)
int flag;
{
if (tnfd)
{
if (flag)
sendbye ();
close (tnfd);
close (tnfd1);
tnfd = 0;
}
}


sendbye ()
{
int code;

if (envsave (&savenv))
{
alarm (20);
puts ("BYE\r\n", &tnobuf);
fflush (&tnobuf);
log ("[ BYE ]");
while ((code = getcode ()) != 231)
if (code < 0)
break;
alarm (0);
}
}


send ()
{
static int curhost;
int result;
int domail;
int hostnum;
char tadr[LINESIZE];
char tfirst[LINESIZE];
char *name;
register char *ptr;

for (ptr = adr.adr_name; !lwsp (*ptr); ptr++);
for (*ptr = '\0'; lwsp (*ptr); ptr++);
for (name = ++ptr; !lwsp (*ptr) && *ptr != '\n'; ptr++);
*ptr = '\0';
host2adr (&net_arpa, TRUE, adr.adr_name, tadr);
hostnum = atoi (tadr);
adr2first (&net_arpa, tadr, tfirst);
if (hostnum != curhost)
{ curhost = hostnum;
if (hostnam)
free (hostnam);
hostnam = strdup (tfirst);
}
printx ("%s at %s: ", name, hostnam);




if ((result = opnnet (hostnum)) == OK)
{ domail = 0;
filesiz = infdsize ();
switch(adr.adr_delv)
{ case DELMAIL:
domail++;
break;
case DELTTY:
result = sndmail(name,"XSEN");
break;
case DELTorM:
result = sndmail(name,"XSEM");
if (result == NODEL || result == TRYAGN)
{ result = sndmail(name,"XSEN");
if (result == NODEL || result == TRYAGN)
domail++;
}
break;
case DELBOTH:
result = sndmail(name,"XMAS");
if (result == NODEL || result == TRYAGN)
{ result = sndmail(name,"XSEN");
if (result == NODEL || result == TRYAGN ||
result == OK)
domail++;
}
break;
}

#ifdef MLFL
if (domail && tnfd)
{ result = sndmlfl (name);
if (result == TRYMAIL)
{
printx ("\nMLFL failed, trying MAIL... ");
result = sndmail (name,"MAIL");
}
}
#endif
#ifndef MLFL
if (domail && tnfd)
result = sndmail (name,"MAIL");
#endif
}
return (result);
}







sndmail (name, ftpcmd)
char name[];
char ftpcmd[];
{
register int result;

if (envsave (&savenv))
{
printx ("checking... ");
alarm (60);
if ((result = mailcmd (name,ftpcmd)) == OK)
{
printx ("sending... ");
alarm (filesiz * 20 + 60);
mailsnd ();
result = mailend ();
}
alarm (0);
}
else
result = TIMEOUT;

return (result);
}





mailcmd (name,ftpcmd)
char name[];
char ftpcmd[];
{
register int code;
int tries;

tries = 0;
retry: puts (ftpcmd, &tnobuf);
putc (' ', &tnobuf);
puts (name, &tnobuf);
puts ("\r\n", &tnobuf);
fflush (&tnobuf);
log ("%s %s", ftpcmd, name);

while ((code = getcode ()) != 350)
switch (code)
{
case NOTOK:
return (BADNET);
case 450:
return (NODEL);
case 504:
if (tries++)
return (BADNET);
if ((code = multics ()) != OK)
return (NODEL);
goto retry;
case 951:
break;
default:
switch (code / 100)
{
case 0:
break;
case 4:
return (TRYAGN);
case 5:
return (NODEL);
default:
return (HOSTERR);
}
}
return (OK);
}





mailsnd ()
{
register int c;
int newline;
struct iobuf inbuf;

newline = 1;
zero(&inbuf, sizeof inbuf);
inbuf.fildes = infd;

while ((c = getc (&inbuf)) > 0)
{
if (c == '\n')
{
newline = 1;
putc ('\r', &tnobuf);
}
else
{
if (newline && c == '.')
putc (' ', &tnobuf);
newline = 0;
}
putc (c, &tnobuf);
}
if (!newline)
puts ("\r\n", &tnobuf);
puts (".\r\n", &tnobuf);
fflush (&tnobuf);

}





mailend ()
{
int code;

while ((code = getcode ()) != 256)
{
switch (code)
{
case NOTOK:
return (BADNET);
case 331:
return (TRYAGN);
default:
switch (code / 100)
{
case 0:
break;
case 2:
return (OK);
case 4:
return (TRYAGN);
case 5:
return (NODEL);
default:
return (HOSTERR);
}
}
}
return (OK);
}


#ifdef MLFL



sndmlfl (name)
char name[];
{
register int result;
int mlflpid;
int status;
register int temp;

mlflpid = mlflsnd ();
if (mlflpid == NOTOK)
{
printx ("can't fork - ");
log ("Can't fork for MLFL");
return (TRYMAIL);
}
if (envsave (&savenv))
{
printx ("checking... ");
alarm (60);
if ((result = mlflcmd (name)) == OK)
{
printx ("sending... ");
alarm (filesiz * 20 + 60);
result = mlflend ();
if (result == OK)
{
while ((temp = waita (&status)) != mlflpid)
if (temp == NOTOK)
{
status = BADNET << 8;
break;
}
mlflpid = 0;
result = status >> 8;
}
}
alarm (0);
}
else
result = TIMEOUT;

if (mlflpid)
{
kill (mlflpid, 9);
while ((temp = waita (&status)) != mlflpid && temp != NOTOK);
}

return (result);
}






mlflcmd (name)
char name[];
{
int tries;
register int code;

tries = 0;
retry: puts ("MLFL ", &tnobuf);
puts (name, &tnobuf);
puts ("\r\n", &tnobuf);
fflush (&tnobuf);
log ("MLFL %s", name);

while ((code = getcode ()) != 250)
switch (code)
{
case NOTOK:
return (BADNET);
case 507:
case 450:
return (NODEL);
case 504:
if (tries++)
return (TRYMAIL);
if ((code = multics ()) != OK)
return (TRYMAIL);
goto retry;
case 255:
case 951:
break;
default:
switch (code / 100)
{
case 0:
break;
case 4:
return (TRYMAIL);
case 5:
return (TRYMAIL);
default:
return (HOSTERR);
}
}
return (OK);
}






mlflsnd ()
{
struct iobuf mlflbuf;
struct netopen openp;
int f;
register int c;
struct iobuf inbuf;

f = fork ();
if (f == 0)
{
zero (&openp, sizeof openp);
openp.o_type = RELATIVE | DIRECT;
openp.o_lskt = 5;
openp.o_relid = tnfd;
openp.o_host = openparam.o_host;
zero (&mlflbuf, sizeof mlflbuf);
if ((mlflbuf.fildes = open ("/dev/net/anyhost", &openp)) >= 0)
{
zero(&inbuf,sizeof inbuf);
inbuf.fildes = infd;

while ((c = getc (&inbuf)) > 0)
{
if (c == '\n')
putc ('\r', &mlflbuf);
putc (c, &mlflbuf);
}
fflush (&mlflbuf);
exit (OK);
}
exit (BADNET);
}
return (f);
}





mlflend ()
{
register int code;

while ((code = getcode ()) != 252)
{
switch (code)
{
case NOTOK:
return (BADNET);
case 331:
return (TRYAGN);
default:
switch (code / 100)
{
case 0:
break;
case 2:
return (OK);
case 4:
return (TRYMAIL);

case 5:
return (TRYMAIL);

default:
return (HOSTERR);

}
}
}
return (OK);
}
#endif








multics ()
{
register int code;

printx ("logging in... ");
puts ("USER NETML\r\n", &tnobuf);
fflush (&tnobuf);
log ("[ USER NETML ]");
while ((code = getcode ()) != 330)
{
if (code < 0)
return (BADNET);
if (code == 230)
return (OK);
if (code >= 400)
return (NODEL);
}

puts ("PASS NETML\r\n", &tnobuf);
fflush (&tnobuf);
log ("[ PASS NETML ]");
while ((code = getcode ()) != 230)
{
if (code < 0)
return (BADNET);
if (code >= 400)
return (NODEL);
}
return (OK);
}


getcode ()
{
register int code;
register int temp;

code = getcod1 ();
if (errline[3] == '-')
while ((temp = getcod1 ()) != code && temp >= 0);
return (code);
}


getcod1 ()
{
register int code;
register int i;
register int c;

i = 0;
while ((c = getc (&tnibuf)) != '\n')
{
if (c < 0)
{
log ("[ closed ]");
return (NOTOK);
}
if (i < ERRLINSIZ && c >= ' ' && c < '\177')
errline[i++] = c;
}
errline[i] = '\0';
code = 0;
for (i = 0; i < 3 && errline[i] >= '0' && errline[i] <= '9'; i++)
code = code * 10 + (errline[i] - '0');
log (errline);
return (code);
}

sysabrt (stat)
int stat;
{
clsnet (1);
exit (stat);
}