1 line
21 KiB
C
Executable File
1 line
21 KiB
C
Executable File
/* Copyright (c) 2017, Computer History Museum
|
|
All rights reserved.
|
|
Redistribution and use in source and binary forms, with or without modification, are permitted (subject to
|
|
the limitations in the disclaimer below) provided that the following conditions are met:
|
|
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
|
disclaimer in the documentation and/or other materials provided with the distribution.
|
|
* Neither the name of Computer History Museum nor the names of its contributors may be used to endorse or promote products
|
|
derived from this software without specific prior written permission.
|
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
|
|
COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|
DAMAGE. */
|
|
|
|
#include "uupc.h"
|
|
#define FILE_NUM 47
|
|
|
|
Boolean SkipToFromLine(void);
|
|
short GetUUPCLip ( TOCHandle destMBox, Boolean isMailbox, short *gotSome);
|
|
|
|
/************************************************************************
|
|
* Incoming from UUPC
|
|
* - We put the pathname in the POP account, preceeded by a !.
|
|
* - Then, it's just a matter of sicking FetchMessageText on each message.
|
|
* --- Well, we make a new RecvLine that returns ".\015" for EOF or
|
|
* a uucp envelope; that helps.
|
|
* --- We also have the luxury of being able to back up and suck in raw
|
|
* binhex/uudecode if the conversion fails
|
|
************************************************************************/
|
|
#pragma segment UUPCIn
|
|
static LineIOP Lip;
|
|
|
|
/************************************************************************
|
|
* GetUUPCMail - read mail from the named mailbox
|
|
************************************************************************/
|
|
short GetUUPCMail(Boolean quietly,short *gotSome)
|
|
{
|
|
#pragma unused(quietly)
|
|
Str255 mailpath;
|
|
short err;
|
|
short anyErr = 0;
|
|
FSSpec spec;
|
|
|
|
/*
|
|
* get the pathname of the maildrop
|
|
*/
|
|
GetPOPPref(mailpath);
|
|
BMD(mailpath+2,mailpath+1,*mailpath-1);
|
|
(*mailpath)--;
|
|
if (mailpath[*mailpath]=='@') --*mailpath;
|
|
Prr = 0;
|
|
|
|
/*
|
|
* make the spec
|
|
*/
|
|
if (!(err=FSMakeFSSpec(Root.vRef,Root.dirId,mailpath,&spec)))
|
|
{
|
|
/*
|
|
* is it empty?
|
|
*/
|
|
if (FSpDFSize(&spec))
|
|
{
|
|
Prr = GetUUPCMailSpec(&spec,quietly,gotSome);
|
|
}
|
|
}
|
|
|
|
if (err)
|
|
FileSystemError(READ_MBOX,mailpath,err);
|
|
else err = Prr;
|
|
|
|
return(err);
|
|
}
|
|
|
|
|
|
short GetUUPCMailSpecToMailBox (FSSpecPtr spec, SInt8 permission, TOCHandle destBox, short *gotSome) {
|
|
short err = noErr;
|
|
Boolean isMailbox = IsMailbox(spec);
|
|
|
|
/* Check for space on the disk */
|
|
if ( Prr = RoomForMessage(FSpDFSize(spec))) {
|
|
FileSystemError(NOT_ENOUGH_ROOM,spec->name,0);
|
|
return Prr;
|
|
}
|
|
|
|
/* allocate the lineio pointer */
|
|
if (Lip)
|
|
DisposePtr((void*)Lip);
|
|
Lip = NuPtrClear(sizeof(*Lip));
|
|
if (!Lip)
|
|
return WarnUser(MEM_ERR,MemError());
|
|
|
|
/* Finally, open the file */
|
|
if (err=FSpOpenLine(spec,permission,Lip))
|
|
Prr = FileSystemError(READ_MBOX,spec->name,err);
|
|
else {
|
|
err = GetUUPCLip ( destBox, isMailbox, gotSome );
|
|
// Should we empty the file?
|
|
// If all worked fine, and we opened the file r/w, then go for it
|
|
if ( err == noErr && permission == fsRdWrPerm && !PrefIsSet(PREF_LMOS) && !CommandPeriod )
|
|
SetEOF(Lip->refN,0);
|
|
// If there was an error, and the user said ok, then go for it
|
|
if (( err != noErr || CommandPeriod ) && ReallyDoAnAlert(CLEAR_DROP_ALRT,Normal)==1 )
|
|
SetEOF(Lip->refN,0);
|
|
CloseLine(Lip);
|
|
DisposePtr((Ptr)Lip);
|
|
Lip = nil;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
short GetUUPCMailSpec (FSSpecPtr spec, Boolean quietly,short *gotSome) {
|
|
#pragma unused ( quietly )
|
|
return GetUUPCMailSpecToMailBox ( spec, fsRdWrPerm, GetInTOC (), gotSome );
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* GetUUPCMailSpec - get mail from a particular filespec
|
|
**********************************************************************/
|
|
short GetUUPCLip ( TOCHandle destMBox , Boolean isMailbox, short *gotSome )
|
|
{
|
|
short err;
|
|
short anyErr = 0;
|
|
TOCHandle inTocH = destMBox;
|
|
short count;
|
|
long oldPos;
|
|
Boolean foundOne = True;
|
|
#ifdef BATCH_DELIVERY_ON
|
|
short batchNum = GetRLong(DELIVERY_BATCH);
|
|
short fetched = 0;
|
|
Boolean inThread=InAThread();
|
|
TOCHandle tocH = GetInTOC ();
|
|
#endif
|
|
|
|
ASSERT ( Lip != NULL );
|
|
ASSERT ( Lip->refN > 0 );
|
|
ASSERT ( gotSome != NULL );
|
|
|
|
CurTrans = UUPCTrans;
|
|
|
|
/*
|
|
* now, grab messages
|
|
*/
|
|
*gotSome = 0;
|
|
if ( !inTocH ) {Prr = 1; goto done;}
|
|
if (isMailbox) SkipToFromLine();
|
|
do
|
|
{
|
|
TOCSetDirty(inTocH,true);
|
|
oldPos = TellLine(Lip);
|
|
ProgressR(NoChange,*gotSome+1,0,UUPC_COPY,nil);
|
|
BadBinHex = False;
|
|
BadEncoding = 0;
|
|
if (!AttachedFiles) AttachedFiles=NuHandle(0);
|
|
SetHandleBig_(AttachedFiles,0);
|
|
if ( destMBox == GetInTOC ())
|
|
count=FetchMessageText(NULL,0,nil,0,NULL);
|
|
else
|
|
count=FetchMessageTextLo(NULL,0,nil,0,inTocH,false,true);
|
|
err = Prr;
|
|
SetHandleBig_(AttachedFiles,0);
|
|
SaveAbomination(nil,0);
|
|
if (!err) err = CommandPeriod;
|
|
anyErr |= err;
|
|
if (err) break;
|
|
#ifdef BAD_ENCODING_HANDLING
|
|
if (!CommandPeriod && (BadBinHex || BadEncoding))
|
|
{
|
|
RecvLine(NULL,nil,nil); /* clear old indicator */
|
|
SeekLine(oldPos,Lip);
|
|
SkipToFromLine();
|
|
NoAttachments = True;
|
|
if (BadBinHex)
|
|
{
|
|
while (count--) DeleteMessageLo(inTocH,(*inTocH)->count-1,True);
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
oldPos = TellLine(Lip);
|
|
NoAttachments = False;
|
|
}
|
|
*gotSome += count;
|
|
#ifdef NEVER // this is a bad idea for reasons I don't entirely understand
|
|
#ifdef BATCH_DELIVERY_ON
|
|
if (count) fetched++;
|
|
if (inThread && tocH && (fetched % batchNum == 0))
|
|
tocH = RenameInTemp(tocH);
|
|
#endif
|
|
#endif
|
|
foundOne = SkipToFromLine();
|
|
}
|
|
while(foundOne);
|
|
done:
|
|
#ifdef BATCH_DELIVERY_ON
|
|
if (inThread && *gotSome && tocH) RenameInTemp(tocH);
|
|
#endif
|
|
anyErr |= err || Prr;
|
|
if (!anyErr) Progress(100,NoBar,nil,nil,nil);
|
|
NoAttachments = False;
|
|
CurTrans = GetTCPTrans();
|
|
return(anyErr);
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* UUPCRecvLine - read a line at a time from the maildrop. Returns ".\015"
|
|
* at the ends of messages.
|
|
************************************************************************/
|
|
OSErr UUPCRecvLine(TransStream stream, UPtr buffer, long *size)
|
|
{
|
|
static Boolean wasFrom;
|
|
static Boolean wasNl=True;
|
|
short lineType;
|
|
|
|
if (MiniEvents()) return(userCancelled);
|
|
if (!buffer) {Boolean retVal = wasFrom; wasFrom = False; return(retVal);}
|
|
wasFrom=False;
|
|
(*size)--;
|
|
|
|
#ifdef DEBUG
|
|
if (*size<100) Debugger();
|
|
#endif
|
|
|
|
ASSERT ( Lip != NULL );
|
|
lineType = GetLine(buffer,*size,size,Lip);
|
|
if (!*size || !lineType || wasNl&&(wasFrom=IsFromLine(buffer)))
|
|
{
|
|
*size = 2;
|
|
buffer[0]='.'; buffer[1]='\015'; buffer[2] = 0;
|
|
}
|
|
else if (lineType && wasNl && *buffer=='.')
|
|
{
|
|
BMD(buffer,buffer+1,*size);
|
|
(*size)++;
|
|
*buffer = '.';
|
|
buffer[*size] = 0;
|
|
}
|
|
wasNl = !lineType || buffer[*size-1]=='\015';
|
|
if (IsRecAudit(stream)) stream->bytesTransferred += *size;
|
|
return(noErr);
|
|
}
|
|
|
|
/************************************************************************
|
|
* SkipToFromLine - skip to the next envelope. Also gives time to others,
|
|
* and keeps track of whether or not we last read a From line.
|
|
************************************************************************/
|
|
Boolean SkipToFromLine(void)
|
|
{
|
|
Str255 buffer;
|
|
long eof, atNow, size;
|
|
short err;
|
|
|
|
ASSERT ( Lip != NULL );
|
|
if (MiniEvents() && CommandPeriod) {Prr = userCancelled; return(False);}
|
|
if ((err = !Lip) || (err=GetEOF(Lip->refN,&eof)))
|
|
{
|
|
FileSystemError(READ_MBOX,GetPOPPref(buffer),err);
|
|
Prr = err;
|
|
return(False);
|
|
}
|
|
atNow = TellLine(Lip);
|
|
if (eof) ByteProgress(nil,atNow,eof);
|
|
if (Lip->eof) return(False);
|
|
if (RecvLine(NULL,nil,nil)) return(True);
|
|
do
|
|
{
|
|
size = sizeof(buffer);
|
|
if (err=RecvLine(NULL,buffer,&size))
|
|
{
|
|
FileSystemError(READ_MBOX,GetPOPPref(buffer),err);
|
|
Prr = err;
|
|
return(False);
|
|
}
|
|
else ByteProgress(nil,-size,0);
|
|
}
|
|
while (size!=2 || *buffer!='.');
|
|
|
|
return(True);
|
|
}
|
|
|
|
#pragma segment UUPCOut
|
|
/************************************************************************
|
|
* Ok; sending mail is more complicated, but it's easier to do
|
|
* SMTP server item has to have the following info, ! separated:
|
|
* - the name of our mac
|
|
* - the name of the remote system (optional, ignored if present)
|
|
* - the path to the spool directory
|
|
* - our user name
|
|
* - our current sequence number
|
|
* ie, !mymac!relay!spoolvol:spooldir:!username!0000
|
|
* - We generate a sequence number, 4 digits (####)
|
|
* - We deposit the mail in D.relay0####, newline-separated
|
|
* - In D.mymac0####, we put commands for the UUCP system, newline-separated
|
|
* --- U username mymac ; this is us
|
|
* --- F D.mymac0#### ; this is the mail file, on the remote system
|
|
* --- I D.mymac0#### ; and we're using it for input
|
|
* --- C rmail <recip-list> ; the command; rmail and recipients as args
|
|
*
|
|
* By declaring our own SendTrans, we actually can use TransmitMessage
|
|
* from sendmail.c, which is tres nice.
|
|
*
|
|
* There are some race conditions in creating the files. So what?
|
|
************************************************************************/
|
|
|
|
typedef struct
|
|
{
|
|
Str255 spoolPath;
|
|
Str63 myMac;
|
|
unsigned char relay[9];
|
|
Str63 userName;
|
|
short sequence;
|
|
short refNs[2];
|
|
Str255 files[2];
|
|
Str31 fileNames[2];
|
|
short oldSeq;
|
|
MessHandle messH;
|
|
} UUXBlock,*UUXPtr,**UUXHandle;
|
|
UUXHandle UUX;
|
|
#define SpoolPath (*UUX)->spoolPath
|
|
#define MyMac (*UUX)->myMac
|
|
#define Relay (*UUX)->relay
|
|
#define UserName (*UUX)->userName
|
|
#define Sequence (*UUX)->sequence
|
|
#define MailRefN (*UUX)->refNs[0]
|
|
#define XRefN (*UUX)->refNs[1]
|
|
#define MailFile (*UUX)->files[0]
|
|
#define XFile (*UUX)->files[1]
|
|
#define Dmymac (*UUX)->fileNames[0]
|
|
#define Xmymac (*UUX)->fileNames[1]
|
|
#define OldSeq (*UUX)->oldSeq
|
|
#define MessH (*UUX)->messH
|
|
|
|
void UUPCGenFilenames(void);
|
|
Boolean UUPCBadFilenames(void);
|
|
int UUPCMakeFiles(void);
|
|
void UUPCKillFiles(void);
|
|
void UUPCCloseFiles(void);
|
|
int UUPCOpenFiles(void);
|
|
int UUPCWriteXFile(CSpecHandle specList);
|
|
int UUPCWriteMailFile(void);
|
|
void UUPCGetNewline(UPtr newline,UPtr buffer);
|
|
/************************************************************************
|
|
* UUPCPrime - get ready
|
|
************************************************************************/
|
|
OSErr UUPCPrime(UPtr server)
|
|
{
|
|
UPtr bangs[6]; /* these will point to exclams in the server text */
|
|
UPtr *bang;
|
|
short err;
|
|
short seq;
|
|
|
|
/*
|
|
* count the bangs, shall we?
|
|
*/
|
|
WriteZero(bangs,sizeof(bangs));
|
|
bangs[0] = server+1; /* first one */
|
|
for (bang=bangs+1;bang<bangs+sizeof(bangs)/sizeof(UPtr);bang++)
|
|
{
|
|
*bang = strchr(bang[-1]+1,'!'); /* look for next exclam */
|
|
if (!*bang) break;
|
|
}
|
|
|
|
if (!bangs[3]) {WarnUser(UUPC_WRONG_SMTP,0);return(1);} /* not enough */
|
|
if (!bangs[4])
|
|
{
|
|
/* relay not included; insert a pretend relay */
|
|
BMD(bangs+1,bangs+2,3*sizeof(UPtr));
|
|
}
|
|
bangs[5] = server+*server+1; /* end of the string */
|
|
|
|
/*
|
|
* allocate some space
|
|
*/
|
|
if (!UUX) UUX=NewZH(UUXBlock);
|
|
if (!UUX) {WarnUser(MEM_ERR,err=MemError());return(err);}
|
|
|
|
/*
|
|
* copy values into it
|
|
*/
|
|
#define MOVE(to,b1,b2) do{ \
|
|
*to=MIN(sizeof(to)-2,bangs[b2]-bangs[b1]-1); to[*to+1]=0; \
|
|
BMD(bangs[b1]+1,to+1,*to); } while (0)
|
|
|
|
MOVE(MyMac,0,1);
|
|
MOVE(SpoolPath,2,3);
|
|
MOVE(UserName,3,4);
|
|
seq = Atoi(bangs[4]+1);
|
|
Sequence = seq;
|
|
|
|
CurTrans = UUPCTrans;
|
|
|
|
return(noErr);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCDry - put away the toys
|
|
************************************************************************/
|
|
OSErr UUPCDry(TransStream stream)
|
|
{
|
|
if (UUX)
|
|
{
|
|
if (*UUX)
|
|
{
|
|
if (Sequence!=OldSeq)
|
|
{
|
|
Str255 smtp;
|
|
GetPref(smtp,PREF_SMTP);
|
|
if (*smtp>4)
|
|
{
|
|
UPtr cp = smtp+*smtp;
|
|
short n=4;
|
|
while (n--)
|
|
{
|
|
*cp-- = Sequence%10+'0';
|
|
Sequence /= 10;
|
|
}
|
|
}
|
|
SetPref(PREF_SMTP,smtp);
|
|
}
|
|
}
|
|
ZapHandle(UUX);
|
|
}
|
|
CurTrans = GetTCPTrans();
|
|
return(noErr);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCSendMessage - the hard work goes here
|
|
************************************************************************/
|
|
int UUPCSendMessage(TOCHandle tocH,short sumNum,CSpecHandle specList)
|
|
{
|
|
short err;
|
|
MessHandle messH;
|
|
|
|
/*
|
|
* grab the message
|
|
*/
|
|
if (!(messH=SaveB4Send(tocH,sumNum))) return(1);
|
|
MessH = messH;
|
|
|
|
/*
|
|
* generate some unique filenames in the spool directory
|
|
*/
|
|
do {UUPCGenFilenames();} while (UUPCBadFilenames());
|
|
err = UUPCMakeFiles();
|
|
if (!err)
|
|
{
|
|
err = UUPCOpenFiles();
|
|
if (!err)
|
|
{
|
|
err = UUPCWriteXFile(specList);
|
|
if (!err) err = UUPCWriteMailFile();
|
|
}
|
|
}
|
|
|
|
UUPCCloseFiles();
|
|
if (err) UUPCKillFiles();
|
|
//else TimeStamp(tocH,sumNum,GMTDateTime(),ZoneSecs());
|
|
return(err);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCGenFilenames - make the filenames
|
|
************************************************************************/
|
|
void UUPCGenFilenames(void)
|
|
{
|
|
Str15 seq;
|
|
int n;
|
|
Str255 scratch;
|
|
Str255 mymacShort;
|
|
|
|
PCopy(mymacShort,MyMac);
|
|
*mymacShort=MIN(7,*mymacShort);
|
|
MyLowerStr(mymacShort);
|
|
|
|
n = ++Sequence;
|
|
seq[0] = 4;
|
|
seq[4] = n%10+'0'; n/=10;
|
|
seq[3] = n%10+'0'; n/=10;
|
|
seq[2] = n%10+'0'; n/=10;
|
|
seq[1] = n%10+'0';
|
|
ComposeRString(scratch,UUPC_DMYMAC,mymacShort,seq); PCopy(Dmymac,scratch);
|
|
ComposeRString(scratch,UUPC_XMYMAC,mymacShort,seq); PCopy(Xmymac,scratch);
|
|
PCopy(MailFile,SpoolPath); PCat(MailFile,Dmymac);
|
|
PCopy(XFile,SpoolPath); PCat(XFile,Xmymac);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCBadFilenames - check that our files don't already exist
|
|
************************************************************************/
|
|
Boolean UUPCBadFilenames(void)
|
|
{
|
|
Str255 scratch;
|
|
short i;
|
|
CInfoPBRec hfi;
|
|
|
|
for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
|
|
{
|
|
PCopy(scratch,(*UUX)->files[i]);
|
|
if (!AHGetFileInfo(0,0,scratch,&hfi)) return(True);
|
|
}
|
|
return(False);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCMakeFiles - create our files
|
|
************************************************************************/
|
|
int UUPCMakeFiles(void)
|
|
{
|
|
Str255 scratch;
|
|
short i,err;
|
|
long creator;
|
|
|
|
GetPref(scratch,PREF_CREATOR);
|
|
if (*scratch!=4) GetRString(scratch,TEXT_CREATOR);
|
|
BMD(scratch+1,&creator,4);
|
|
|
|
for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
|
|
{
|
|
PCopy(scratch,(*UUX)->files[i]);
|
|
if (err=HCreate(0,0,scratch,creator,'TEXT'))
|
|
return(FileSystemError(TEXT_WRITE,scratch,err));
|
|
}
|
|
return(False);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCCloseFiles - close our files
|
|
************************************************************************/
|
|
void UUPCCloseFiles(void)
|
|
{
|
|
short i;
|
|
for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
|
|
if ((*UUX)->refNs[i]) (void) MyFSClose((*UUX)->refNs[i]);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCKillFiles - destroy our files
|
|
************************************************************************/
|
|
void UUPCKillFiles(void)
|
|
{
|
|
Str255 scratch;
|
|
short i;
|
|
for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
|
|
{
|
|
PCopy(scratch,(*UUX)->files[i]);
|
|
(void) HDelete(0,0,scratch);
|
|
}
|
|
Sequence--;
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCOpenFiles - open our files
|
|
************************************************************************/
|
|
int UUPCOpenFiles(void)
|
|
{
|
|
FSSpec spec;
|
|
Str255 scratch;
|
|
short i,err,refN;
|
|
|
|
for (i=0;i<sizeof((*UUX)->refNs)/sizeof(short);i++)
|
|
{
|
|
PCopy(scratch,(*UUX)->files[i]);
|
|
FSMakeFSSpec(0,0,scratch,&spec);
|
|
if (err=FSpOpenDF(&spec,fsRdWrPerm,&refN))
|
|
return(FileSystemError(TEXT_WRITE,scratch,err));
|
|
(*UUX)->refNs[i] = refN;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCWriteXFile - write the file to send to the other side for execution
|
|
************************************************************************/
|
|
int UUPCWriteXFile(CSpecHandle specList)
|
|
{
|
|
short err;
|
|
Str255 buffer;
|
|
Str15 newline;
|
|
Accumulator newsGroupAcc;
|
|
|
|
LDRef(UUX);
|
|
|
|
ComposeRString(buffer,UUPC_U_CMD,UserName,MyMac);
|
|
err = FSWriteP(XRefN,buffer);
|
|
|
|
if (!err)
|
|
{
|
|
UUPCGetNewline(newline,buffer);
|
|
|
|
ComposeRString(buffer,UUPC_F_CMD,Dmymac);
|
|
err = FSWriteP(XRefN,buffer);
|
|
|
|
if (!err)
|
|
{
|
|
ComposeRString(buffer,UUPC_I_CMD,Dmymac);
|
|
err = FSWriteP(XRefN,buffer);
|
|
|
|
if (!err)
|
|
{
|
|
UL(UUX);
|
|
GetRString(buffer,UUPC_C_CMD);
|
|
err = FSWriteP(XRefN,buffer);
|
|
|
|
Zero(newsGroupAcc);
|
|
if (!err) err=DoRcptTos(NULL,MessH,False,specList,&newsGroupAcc);
|
|
(*MessH)->newsGroupAcc = newsGroupAcc;
|
|
if (!err) err=FSWriteP(XRefN,newline);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (err) FileSystemError(TEXT_WRITE,XFile,err);
|
|
UL(UUX);
|
|
return(err);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCWriteMailFile - get the message into the file
|
|
************************************************************************/
|
|
int UUPCWriteMailFile(void)
|
|
{
|
|
MSumType sum;
|
|
Str255 envelope;
|
|
short len;
|
|
Str15 oldNewLine;
|
|
short err;
|
|
|
|
PCopy(sum.from,UserName);
|
|
*envelope = SumToFrom(&sum,envelope+1);
|
|
|
|
LDRef(UUX);
|
|
ComposeRString(envelope+*envelope,UUPC_REMOTE,MyMac);
|
|
UL(UUX);
|
|
|
|
len = *envelope;
|
|
*envelope += envelope[len];
|
|
envelope[len] = ' ';
|
|
if (err=FSWriteP(MailRefN,envelope))
|
|
{
|
|
PCopy(envelope,MailFile);
|
|
FileSystemError(TEXT_WRITE,envelope,err);
|
|
return(err);
|
|
}
|
|
|
|
PCopy(oldNewLine,NewLine);
|
|
UUPCGetNewline(NewLine,envelope);
|
|
err = TransmitMessageHi(NULL,MessH,False,False);
|
|
PCopy(NewLine,oldNewLine);
|
|
return(err);
|
|
}
|
|
|
|
/**********************************************************************
|
|
* WriteMailFile - write a fully-formatted piece of mail to a file
|
|
**********************************************************************/
|
|
OSErr WriteMailFile(MessHandle messH,short refN,Boolean mime,emsMIMEHandle *tlMIME)
|
|
{
|
|
UUXHandle oldUUX = UUX;
|
|
UUXHandle newUUX = NewZH(UUXBlock);
|
|
TransVector oldTrans = CurTrans;
|
|
OSErr err;
|
|
Str15 oldNewLine;
|
|
Boolean oldUUPCOut=UUPCOut;
|
|
|
|
if (!newUUX) return(MemError());
|
|
|
|
UUPCOut = True;
|
|
UUX = newUUX;
|
|
MailRefN = refN;
|
|
MessH = messH;
|
|
CurTrans = UUPCTrans;
|
|
PCopy(oldNewLine,NewLine);
|
|
if (!tlMIME)
|
|
PCopy(NewLine,Cr);
|
|
else
|
|
PCopy(NewLine,CrLf);
|
|
|
|
err = TransmitMessage(NULL,MessH,False,True,!mime,tlMIME,False);
|
|
|
|
PCopy(NewLine,oldNewLine);
|
|
UUX = oldUUX;
|
|
ZapHandle(newUUX);
|
|
CurTrans = oldTrans;
|
|
UUPCOut = oldUUPCOut;
|
|
return(err);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUCPWriteAddr - write an address to the X file
|
|
************************************************************************/
|
|
int UUPCWriteAddr(UPtr addr)
|
|
{
|
|
Str255 buffer;
|
|
short err;
|
|
|
|
if (!XRefN) return(noErr);
|
|
*buffer = 1;
|
|
buffer[1] = ' ';
|
|
PCat(buffer,addr);
|
|
if (err=FSWriteP(XRefN,buffer))
|
|
{
|
|
PCopy(buffer,XFile);
|
|
FileSystemError(TEXT_WRITE,buffer,err);
|
|
}
|
|
return(err ? 500 : 0);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCGetNewline - what's this guy using for a newline?
|
|
************************************************************************/
|
|
void UUPCGetNewline(UPtr newline,UPtr buffer)
|
|
{
|
|
UPtr bp;
|
|
for (bp=buffer+*buffer;bp[-1]<' ';bp--);
|
|
*newline = (buffer+*buffer)-bp+1;
|
|
BMD(bp,newline+1,*newline);
|
|
}
|
|
|
|
/************************************************************************
|
|
* UUPCSendTrans - sendtrans to a file
|
|
************************************************************************/
|
|
OSErr UUPCSendTrans(TransStream stream, UPtr text,long size, ...)
|
|
{
|
|
long bSize;
|
|
short err;
|
|
|
|
if (size==0) return(noErr); /* allow vacuous sends */
|
|
if (MiniEvents()) return(userCancelled);
|
|
|
|
bSize = size;
|
|
if (err=AWrite(MailRefN,&bSize,text))
|
|
return(FileSystemError(TEXT_WRITE,MailFile,err));
|
|
|
|
if (IsSendAudit(stream)) stream->bytesTransferred += bSize;
|
|
|
|
{
|
|
Uptr buffer;
|
|
va_list extra_buffers;
|
|
va_start(extra_buffers,size);
|
|
while (buffer = va_arg(extra_buffers,UPtr))
|
|
{
|
|
bSize = va_arg(extra_buffers,int);
|
|
if (err=UUPCSendTrans(nil,buffer,bSize,nil)) break;
|
|
}
|
|
va_end(extra_buffers);
|
|
}
|
|
return(err);
|
|
}
|
|
|
|
/************************************************************************
|
|
* GenSendWDS - send a lot of text to the remote host.
|
|
************************************************************************/
|
|
OSErr GenSendWDS(TransStream stream,wdsEntry *theWDS)
|
|
{
|
|
#pragma unused (stream)
|
|
short err=0;
|
|
|
|
CycleBalls();
|
|
for (;theWDS->length;theWDS++)
|
|
if (err=SendTrans(nil,theWDS->ptr,theWDS->length,nil)) break;
|
|
|
|
return(err);
|
|
}
|