home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
OS2OMAIL.ZIP
/
OMAIL.C
< prev
next >
Wrap
Text File
|
1989-05-21
|
23KB
|
858 lines
/*--------------------------------------------------------------------------*/
/* Usual Legal BS goes here. Copyright 1988, 1989, Doug Boone */
/* */
/* You're free to use and modify this program however you want, so long as */
/* 1: Keep it free, you probably didn't pay me for it. */
/* 2: Keep it friendly, don't abuse the power of FidoNet mail and requests */
/* 3: Keep it legal. */
/* */
/* MSC 5.1|IBM C/2: MAKE FAMOMAIL.EXE (gives both protected and API EXE) */
/* */
/* For Opus 1.10 Gamma VI: */
/* MSC 5.1|IBM C/2: add /DPOLL110 in MAKEFILE */
/* */
/* Doug Boone (916) 893-9019 data (FidoNet 119/5) */
/* (916) 891-0748 voice (Pacific Standard Time) */
/* */
/* Modified for Protected and Family API operation (OS/2, DOS) by */
/* Bill Andrus, FidoNet 1:109/301, (703) 323-7654 (BBS). */
/* */
/* Thanks to Steve Antonoff who added the code to send to nodes in the same */
/* net and Steve Barnes who suggested the QLO change (although I don't know */
/* what it does.) */
/* */
/* "Don't rip me off!" -- Tom Jennings (buried in the Fido 11 code) */
/* (tabs are at 4) */
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/* Include files */
/*--------------------------------------------------------------------------*/
#include <errno.h>
#include <dos.h>
#include <stdlib.h>
#include <sys\types.h>
#define INCL_DOSPROCESS
#include <OS2.h>
#include <sys\stat.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <malloc.h>
#include <opus.h>
/*--------------------------------------------------------------------------*/
/* Static function declarations */
/*--------------------------------------------------------------------------*/
void do_append(unsigned int);
void change(char);
void noaddr(void);
void usage(void);
void oops(char *,char *);
int get_node(char *,int,int);
void do_req(char *);
void get_names(char *);
void do_polls(void);
void do_stops(void);
int check(char *);
#ifdef POLL110
void poll_110(int,int,char *);
#endif
/*--------------------------------------------------------------------------*/
/* Static variable definitions */
/*--------------------------------------------------------------------------*/
/*
struct _dta {
char reserved[21];
char attribute;
unsigned time;
unsigned date;
long size;
char name[13];
} fileinfo; */
static struct find_t fileinfo;
static struct _FILEFINDBUF InfoBuf;
/*--------------------------------------------------------------------------*/
/* External variable declarations */
/*--------------------------------------------------------------------------*/
/* ... NONE ... */
/*--------------------------------------------------------------------------*/
/* Locally defined globals */
/*--------------------------------------------------------------------------*/
HDIR hDir;
USHORT cSearch;
USHORT usAttrib;
/*--------------------------------------------------------------------------*/
/* Local constants */
/*--------------------------------------------------------------------------*/
#define FILENAMELEN 13
#define PROD_CODE 9
#define MAX_PATH 80
#define POLL 0x0001 /* Polling an address */
#define REQUEST 0x0002 /* WaZoo request */
#define SEND 0x0004 /* File Attach */
#define TRUNC 0x0104 /* (08+04) File Attach, Truncate after send */
#define KILL_SEND 0x0204 /* (0f+04) File Attach, Kill after send */
#define UPDATE 0x0102 /* Ask for an update for file */
#define HOLD 0x0010 /* Change outbound mail to Hold */
#define CRASH 0x0020 /* Change outbound mail to Crash */
#define DIRECT 0x0040 /* Change outbound mail to Direct */
#define STOP 0x0080 /* Mark these nodes as nocalls */
#ifdef POLL110
#define POLL_110 0x1000 /* Temporary 1.10 poll with DUT file */
#endif
struct onecatch {
int node;
int net;
char firstchar;
};
struct onecatch address[25];
int file;
int action = 0;
char pwd[9];
int add_count=0;
char *def_path ="C:\\Outbound";
char *fill1 ="***********************************";
#ifdef POLL110
#ifdef ME
int o_net = 119; /* Originating Net */
int o_node = 5; /* Originating Node */
#else
int o_net = 0x1234; /* Originating Net */
int o_node = 0x5678; /* Originating Node */
#endif
#endif
char matrix_path[MAX_PATH];
char in_path[MAX_PATH];
char out_path[MAX_PATH];
main(argc,argv)
char *argv[];
int argc;
{
int k;
int i;
char *files[30];
char *sptr;
int fcount = 0;
/* Process the "-" switches */
memset(pwd,0,9);
if (argc<3)
usage();
action = check(argv[1]);
if (action == 0)
usage();
strcpy(matrix_path,def_path);
for (i=2; i<argc; i++) {
sptr = argv[i];
if (*sptr == '!') strcpy(pwd,argv[i]);
else if((*sptr == '-') ||
(*sptr == '/')) {
switch(*(sptr+1)){
#ifdef POLL110
case 'O' :
case 'o' : sptr++;
o_net = atoi(++sptr);
sptr = strchr(sptr,'/');
o_node = atoi(++sptr);
break;
#endif
case '$' :
case 'S' :
case 's' : if (strlen(sptr)>2)
add_count+=get_node(sptr+2,add_count,'$');
else
noaddr();
break;
case 'H' :
case 'h' : if (strlen(sptr)>2)
add_count+=get_node(sptr+2,add_count,'H');
else
noaddr();
break;
case 'Q' :
case 'q' : if (strlen(sptr)>2)
add_count+=get_node(sptr+2,add_count,'Q');
else
noaddr();
break;
case 'D' :
case 'd' :
#ifndef POLL110
case 'O' :
case 'o' :
#endif
case 'N' :
case 'n' : if (strlen(sptr)>2)
add_count+=get_node(sptr+2,add_count,'D');
else
noaddr();
break;
case 'C' :
case 'c' : if (strlen(sptr)>2)
add_count+=get_node(sptr+2,add_count,'C');
else
noaddr();
break;
case 'P' :
case 'p' : strcpy(matrix_path,sptr+2);
if (matrix_path[strlen(matrix_path)-1] == '\\')
matrix_path[strlen(matrix_path)-1]='\0';
break;
default : cprintf("I don't understand '%s' skipping it.\r\n",sptr);
break;
}
}
else {
if (((strchr(sptr,'/')) != NULL) &&
(atoi(sptr) != 0)) {
switch(action) {
case STOP : add_count += get_node(sptr,add_count,'$'); break;
case SEND : add_count += get_node(sptr,add_count,'D'); break;
case REQUEST: add_count += get_node(sptr,add_count,'D'); break;
case UPDATE : add_count += get_node(sptr,add_count,'D'); break;
case POLL : add_count += get_node(sptr,add_count,'D'); break;
case HOLD : add_count += get_node(sptr,add_count,'H'); break;
case DIRECT : add_count += get_node(sptr,add_count,'D'); break;
case CRASH : add_count += get_node(sptr,add_count,'C'); break;
case TRUNC : add_count += get_node(sptr,add_count,'D'); break;
case KILL_SEND: add_count += get_node(sptr,add_count,'D'); break;
}
}
else {
files[fcount] = (char *) malloc(1 + strlen(argv[i]));
strcpy(files[fcount],strupr(argv[i]));
if (fcount <30)
fcount++;
}
}
}
if (action & REQUEST || action & SEND) {
for (i = 0;i < fcount;i++) {
if (action & REQUEST)
do_req(files[i]);
else if (action & SEND)
get_names(files[i]);
}
}
else if (action == STOP)
do_stops();
else if (action == POLL)
do_polls();
else {
switch(action) {
case HOLD : change('H');
break;
case DIRECT : change('D');
break;
case CRASH : change('C');
break;
}
}
exit(0);
}
int check(char *what) {
if (stricmp(what,"poll")==0)
return(POLL);
if (stricmp(what,"get")==0)
return(REQUEST);
if (stricmp(what,"send")==0)
return(SEND);
if (stricmp(what,"stop")==0)
return(STOP);
if (stricmp(what,"hold")==0)
return(HOLD);
if (stricmp(what,"crash")==0)
return(CRASH);
if (strnicmp(what,"norm",4)==0)
return(DIRECT);
if (strnicmp(what,"dir",3)==0)
return(DIRECT);
if (strnicmp(what,"trunc",5)==0)
return(TRUNC);
if (strnicmp(what,"kill",4)==0)
return(KILL_SEND);
if (strnicmp(what,"update",4)==0)
return(UPDATE);
return(0);
}
void do_stops(void) {
int send;
int errno;
int done;
char stop[MAX_PATH];
FILE *fp;
struct find_t find;
for (send=0;send<add_count;send++){
sprintf(stop,"%s\\%04X%04X.$$?", matrix_path,address[send].net,address[send].node);
done = dir_findfirst(stop,_A_NORMAL,&find);
if (done == 0) {
sprintf(stop,"%s\\%s", matrix_path,find.name);
unlink(stop);
}
sprintf(stop,"%s\\%04X%04X.$$5", matrix_path,address[send].net,address[send].node);
printf("Marking %d/%d as a no-send!\n",address[send].net,address[send].node);
errno = 0;
fp = fopen(stop,"at");
if (errno){
cprintf("Can't open $$5 file (%s)\r\n",stop);
usage();
}
fclose(fp);
}
return;
}
void do_polls(void) {
int send,errno;
char path_out[64],flow[64];
int done,k;
FILE *outbound;
for (send=0;send<add_count;send++) {
#ifdef POLL110
sprintf(path_out,"%s\\%04X%04X.%cUT",
matrix_path,address[send].net,address[send].node,address[send].firstchar);
poll_110(address[send].net,address[send].node,path_out);
#else
sprintf(path_out,"%s\\%04X%04X.%cLO",
matrix_path,address[send].net,address[send].node,address[send].firstchar);
errno=0;
outbound=fopen(path_out,"at");
fclose(outbound);
if (!errno)
printf("Creating %cLO file for %d/%d\n",
address[send].firstchar,address[send].net,address[send].node);
else {
cprintf("Can't open FLO file (%s)\r\n",path_out);
usage();
}
#endif
}
}
void get_names(char *local) {
struct find_t c_file;
char path1[64];
char names[31][13];
char *tmp;
FILE *fp;
int d;
int i;
int done;
int send;
int file_count;
int errno;
char path_out[MAX_PATH];
strcpy(path1,local);
if ((tmp = strrchr(path1,'\\')) != NULL) {
tmp++;
*tmp = 0x00;
}
else if ((tmp = strchr(path1,':')) != NULL) {
tmp++;
*tmp = 0x00;
}
else /* if no path specified, make one */
getcwd(path1,MAX_PATH);
if (path1[strlen(path1)-1] != '\\')
strcat(path1,"\\");
file_count=0;
done=dir_findfirst(local,_A_NORMAL,&c_file);
while (!done && file_count < 30) {
strcpy(names[file_count],c_file.name);
file_count++;
done = dir_findnext(&c_file);
}
if (file_count==0)
cprintf("No files: '%s' \n\n",local);
if (file_count>0){
for (send=0;send<add_count;send++){
sprintf(path_out,"%s\\%04X%04X.%cLO",
matrix_path, address[send].net, address[send].node,
address[send].firstchar);
errno = 0;
fp = fopen(path_out,"at");
if (errno){
cprintf("Can't open FLO file (%s)\r\n",path_out);
usage();
}
for (i=0;i<file_count;i++){
if (action == TRUNC)
fprintf(fp,"#%s%s\n",path1,names[i]);
else if (action == KILL_SEND)
fprintf(fp,"^%s%s\n",path1,names[i]);
else
fprintf(fp,"%s%s\n",path1,names[i]);
printf("%s%s to %d/%d\n", path1, names[i],
address[send].net, address[send].node);
if (errno){
cprintf("Error %d. Writing %s\n",errno,path_out);
exit(1);
}
}
fclose(fp);
}
}
return;
}
void do_req(char *local) {
int send;
FILE *fp;
char path_out[MAX_PATH];
char *check;
int done;
struct find_t c_file;
long filetime = 0L;
struct stat *buf;
char *npath;
char *ch;
do_polls();
buf = (struct stat *) malloc(sizeof(struct stat));
npath = (char *) malloc(80);
for (send=0;send<add_count;send++)
{
/*--------------------------------------------------------------------*/
/* Create or append the REQ file */
/*--------------------------------------------------------------------*/
sprintf(path_out,"%s\\%04x%04x.REQ", matrix_path,
address[send].net, address[send].node);
fp = fopen(path_out,"at");
if (fp==NULL) oops("Unable to open the Request file",NULL);
/*--------------------------------------------------------------------*/
/* Write the file names to the REQ file */
/*--------------------------------------------------------------------*/
if (action == UPDATE) {
tzset();
strcpy(npath,local);
if ((ch = strrchr(npath,'\\')) != NULL)
++ch;
else if ((ch = strrchr(npath,':')) != NULL)
++ch;
else
ch = npath;
done=dir_findfirst(local,_A_NORMAL,&c_file);
while (done == 0) {
strcpy(ch,c_file.name);
stat(npath,buf);
buf->st_atime -= timezone;
if (filetime < buf->st_atime)
filetime = buf->st_atime;
done = dir_findnext(&c_file);
}; /* end of while loop */
if ((check = strrchr(local,'\\')) == NULL) {
if ((check = strrchr(local,':')) == NULL)
check = local;
else
check++;
}
else
check++;
if (strlen(pwd) > 0)
fprintf(fp,"%s %s +%09ld\n",check,pwd,filetime);
else
fprintf(fp,"%s +%09ld\n",check,filetime);
fclose(fp);
} /* End of file update checking */
else {
if (strlen(pwd) > 0)
fprintf(fp,"%s %s\n",local,pwd);
else
fprintf(fp,"%s\n",local);
fclose(fp);
}
} /* for */
free(buf);
free(npath);
return;
}
int get_node(char *arg,int add_count,int prefix)
{
address[add_count].firstchar = prefix;
if (strchr(arg,'/'))
sscanf(arg,"%d/%d",&address[add_count].net,&address[add_count].node);
else {
if (add_count) {
address[add_count].net = address[add_count -1].net;
address[add_count].node = atoi(arg);
}
else {
printf("Must supply NET for first destination - %s ignored\n",
arg);
return(0);
}
}
return(1);
}
void oops(message,argument)
char *message,*argument;
{
cprintf( "\r\n\nERR: %s", message );
if (argument) cprintf(" (%s)",argument);
cputs("\r\n\n");
usage();
}
/* -----------------------------------------------
USAGE
----------------------------------------------- */
void usage(void) {
printf("\n\n\n\tUSAGE: \n\n");
printf("Omail [POLL][GET][SEND][STOP] [FILE(s)] -[S][C][H][D]Net/Node [!Password]\n");
printf(" [-POutbound\Path\]\n\n");
printf("The first arguement must be one of these.\n\n");
printf("POLL ....... Generate a Null *.?LO file for each Net/Node listed\n");
printf("GET ........ WaZoo Request File(s) from Net/Node (may need !Password) \n");
printf("UPDATE ..... Ask for a file update. Give your file's FULL PATH!!\n");
printf("SEND ....... Send File(s) to Net/Node\n");
printf("TRUNC ...... Send File(s) to Net/Node, and then set it to 0 length\n");
printf("KILL ....... Send File(s) to Net/Node, and then delete it (Binkley!!)\n");
printf("STOP ....... Create a *.$$5 file to stop outbound calls.\n");
printf("HOLD ....... Change any mail for the boards on the command line to hold.\n");
printf("CRASH ...... Change any mail for the boards on the command line to crash.\n");
printf("DIRECT ..... Change any mail for the boards on the command line to direct.\n");
printf("You may Poll/Send/Get to/from multiple boards and files, but each Net/Node \n");
printf("MUST begin with the -[c][h][d] where:\n\n");
printf("\tC ........ Continuous Mail packet is created.\n");
printf("\tH ........ Hold Mail packet is created.\n");
printf("\tD ........ Direct Mail packet is created.\n");
printf("\tS ........ Used only to stop calls to a board\n");
printf("\tQ ........ Used with Binkley >2.10 to generate turn-around list\n");
printf("\tP ........ Change the outbound path from the default C:\OUTBOUND\n");
printf("\t to match whatever you use.\n\n");
printf("You can operate on multiple boards, but you can carry on one TYPE of \n");
printf("transaction each run. If you need to use a password with a file-request\n");
printf("then only the LAST password entered will have any effect. Be careful!\n");
printf("Some of these commands may not work with your mailer!\n\t\t\t\t\t\tDoug Boone 119/5 \n");
exit(1);
}
void noaddr(void) {
printf("\n No address listed, skipping\n");
}
#ifdef POLL110
void poll_110(int d_net,int d_node,char *path_out) {
int outfp;
int i;
struct tm *tm_now;
time_t now;
struct _pkthdr *header;
char *fixup;
if (access(path_out,0) == 0)
return;
header = (struct _pkthdr *) malloc(sizeof(struct _pkthdr)+1);
time(&now);
tm_now = gmtime(&now);
outfp = open(path_out,O_BINARY|O_RDWR|O_CREAT,S_IREAD|S_IWRITE);
/* Update the packet header to reflect that its been messed with */
header->orig_node = o_node;
header->dest_node = d_node;
header->year = tm_now->tm_year + 1900;
header->month = tm_now->tm_mon + 1;
header->day = tm_now->tm_mday;
header->hour = tm_now->tm_hour;
header->minute = tm_now->tm_min;
header->second = tm_now->tm_sec;
header->rate = 0;
header->ver = 2;
header->orig_net = o_net;
header->dest_net = d_net;
header->product = PROD_CODE;
header->x1 = 0x00;
for (i=0;i<6;i++)
header->pktpwd[i] = 0x00;
for (i=0;i<2;i++)
header->B_fill1[i] = 0x00;
header->Orig_Zone = 0x00;
header->Dest_Zone = 0x00;
for (i=0;i<16;i++)
header->B_fill2[i] = 0x00;
header->B_fill3 = 0L;
i = write(outfp,header,sizeof(struct _pkthdr));
if (i<60) {
i = 60 - i;
fixup = (char *) malloc(i+1);
memset(fixup,0x00,i);
write(outfp,fixup,i);
free(fixup);
}
close(outfp);
printf("Creating %s for %d/%d\n", path_out,d_net,d_node);
free(header);
return;
}
#endif
void change(char act) {
int i;
char temp_path[MAX_PATH];
char *temp_buffer;
int done;
unsigned int check;
unsigned int written;
int buff_size;
char *result;
char name[13];
int inhandle,outhandle;
struct find_t find;
for (i=0;i < add_count;i++) {
sprintf(temp_path,"%s\\%04X%04X.?LO",matrix_path,address[i].net,address[i].node);
sprintf(out_path,"%s\\%04X%04X.%cLO",matrix_path,address[i].net,address[i].node,act);
done = dir_findfirst(temp_path,_A_NORMAL,&find);
while (done == 0) {
strcpy(name,find.name);
buff_size = find.size;
strupr(name);
result = strchr(name,'.');
result++;
if (*result != act) {
sprintf(in_path,"%s\\%s",matrix_path,name);
if ((rename(in_path,out_path)) != 0) {
temp_buffer = (char *) malloc(buff_size+1);
inhandle = open(in_path,O_RDONLY|O_BINARY);
outhandle = open(out_path,O_APPEND|O_BINARY|O_WRONLY);
printf("Appending: %s\nTo: %s\n",in_path,out_path);
do {
check = read(inhandle,temp_buffer,buff_size);
if (check)
written = write(outhandle,temp_buffer,check);
} while (check > 0);
close(inhandle);
close(outhandle);
if (written != 0xfffe)
unlink(in_path);
free(temp_buffer);
} /* Done copying FLO if rename failed */
else
printf("Renaming: %s\nTo: %s\n",in_path,out_path);
} /* Done with rename/copy file to new name */
done = dir_findnext(&find);
} /* Done with *.?LO Files Go do *.?UT files */
sprintf(temp_path,"%s\\%04X%04X.?UT",matrix_path,address[i].net,address[i].node);
sprintf(out_path,"%s\\%04X%04X.%cUT",matrix_path,address[i].net,address[i].node,act);
done = dir_findfirst(temp_path,_A_NORMAL,&find);
while (done == 0) {
strcpy(name,find.name);
buff_size = find.size;
strupr(name);
result = strchr(name,'.');
result++;
if (*result != act) {
sprintf(in_path,"%s\\%s",matrix_path,name);
if ((rename(in_path,out_path)) != 0) {
if (buff_size > 60)
do_append(buff_size);
} /* Done copying FLO if rename failed */
else
printf("Renaming: %s\nTo: %s\n",in_path,out_path);
} /* Done with rename/copy file to new name */
done = dir_findnext(&find);
} /* Done handling *.?UT files */
} /* End of main for(;;) loop */
return;
}
void do_append(unsigned int size) {
int infp,outfp;
struct tm *tm_now;
time_t now;
struct _pkthdr *header;
char *copy;
unsigned int buff_size;
unsigned int go;
printf("Appending: %s\nTo: %s\n", in_path,out_path);
header = (struct _pkthdr *) malloc(sizeof(struct _pkthdr)+1);
time(&now);
tm_now = localtime(&now);
outfp = open(out_path,O_BINARY|O_RDWR);
infp = open(in_path,O_BINARY|O_RDONLY);
go = read(outfp,header,sizeof(struct _pkthdr));
lseek(outfp,0L,SEEK_SET);
/* Update the packet header to reflect that its been messed with */
header->year = tm_now->tm_year + 1900;
header->month = tm_now->tm_mon + 1;
header->day = tm_now->tm_mday;
header->hour = tm_now->tm_hour;
header->minute = tm_now->tm_min;
header->second = tm_now->tm_sec;
header->product = PROD_CODE;
go = write(outfp,header,sizeof(struct _pkthdr));
free(header);
lseek(outfp,-2L,SEEK_END);
lseek(infp,((long)sizeof(struct _pkthdr)),SEEK_SET);
size -= sizeof(struct _pkthdr);
buff_size = size;
if ((copy = (char *) malloc(buff_size)) == NULL) {
do {
buff_size = (buff_size/10) * 9;
copy = (char *) malloc(buff_size);
} while (copy == NULL);
}
do {
go = read(infp,copy,buff_size);
go = write(outfp,copy,go);
size -= buff_size;
if (buff_size > size)
buff_size = size;
} while (size > 0);
free(copy);
close(infp);
close(outfp);
if (go > 0)
unlink(in_path);
else
printf("\nError appending %s to %s\n\n",in_path,out_path);
return;
}
int
dir_findfirst(char * filename, int attribute, struct find_t * dta)
{
hDir = 0xffff;
usAttrib = 0;
cSearch = 1;
if (DosFindFirst( filename
, &hDir
, usAttrib
, &InfoBuf
, (USHORT)( sizeof(InfoBuf) * cSearch )
, &cSearch
, (ULONG)NULL ) != 0 )
{
DosFindClose( hDir );
errno = ENOENT;
return (-1);
} else {
dta->size = InfoBuf.cbFile;
strcpy( dta->name, InfoBuf.achName);
errno = 0;
return (0);
}
}
int
dir_findnext(struct find_t * dta)
{
if ((DosFindNext( hDir
, &InfoBuf
, (USHORT)(FILENAMELEN + 23)
, &cSearch)
) || (cSearch != 1))
{
DosFindClose( hDir );
errno = ENOENT;
return (-1);
} else {
dta->size = InfoBuf.cbFile;
strcpy( dta->name, InfoBuf.achName);
errno = 0;
return (0);
}
}