home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
UTILITY
/
UU121B11.ARJ
/
UU.C
next >
Wrap
Text File
|
1991-12-03
|
38KB
|
1,376 lines
/* The UU???.MOD and UU???.EXE source file. See version number defined
below. This file can be used to produce the obj file UU.OBJ, for use
with WWIV version 4.20 or the stand alone EXE file UU.EXE.
To produce the EXE version simply remove the #define for MOD below and
compile. An example .PRJ (UU.PRJ) is included. The project file, for
TC++, will require some changes to work for you. The paths and
directories are set up for my system. It uses the large memory model
and duplicate strings are merged.
The EXE version requires two support files be placed in the same
directory in which the EXE resides. These files, UU.CFG and UU.HLP,
are included in the archive UU???.ZIP.
To install the mod, remove void extract_out(char *b, long len, char
*title) from msgbase1.c. Make sure the line: #define MOD
is still in the source file uu.c and has not been removed to produce the
EXE. Add uu.c to your makefile or project. Put uu.c in your source
directory, make fcns and make. Detailed instructions for doing
this are included as UU.MOD in the archive UU???.ZIP.
The MOD version requires three support files be placed in the GFILES
directory. These files, UU1.MSG (the main menu for UU???.MOD),
UU2.MSG (a sub menu for UU???.MOD), and zipcomnt.msg (a comment to be
added to all extracted and zipped files) are included in the archive
UU???.ZIP.
If you make changes be careful. Some functions are used only for the
MOD, some only for the EXE and some for both. Extreme care must be
used when changing those functions used by both. It is very easy to
change the mod to do something you want; only to find the EXE no longer
works. If it aint broke don't fix it. Tell me about it.
You are welcome to use this file as you see fit; but you must not
distribute modified versions of this file. It must be included, intact,
in any file which describes enhancements or changes.
Jim Wire
HIT BBS
(319) 296-1529
*/
#define UU_VER_NO "1.21b11"
#define UU_DATE "12/03/91"
#define MOD
#define SWITCH
#ifdef MOD
#include "vars.h"
#pragma hdrstop
#include <dir.h>
#else
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <stdlib.h>
#include <dir.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <sys\types.h>
#endif
char buf[80];
char in_path[MAXPATH];
char out_path[MAXPATH];
char home_path[MAXPATH];
int out_file_specified;
long count=0L;
long size=18000L;
int line=300;
int seg=1;
int segs=1;
int mode;
int uu_type=1;
#ifndef SWITCH
/* This little guy deletes a file. I use him in other areas on my bbs.
I put him in utility.c, so he does not get overlayed. I found him
to be of particular value with Adam Caldwell's editinfo.mod. Call
delete_file everywhere he uses remove. As a matter of fact you might
want to replace all calls to unlink and remove in the BBS to delete_file
calls.
*/
void delete_file(char *file_name) /* Not WITH SWITCH MOD */
{
char s[161];
int res=0;
if(!exist(file_name))
return;
res=unlink(file_name);
if(res==0)
return;
_chmod(file_name,1,0);
res=unlink(file_name);
if(res==0)
return;
#ifdef MOD
npr("6Unable to delete the file %s.0\r\n",file_name);
#else
sprintf(s,"Unable to delete the file %s.\r\n",file_name);
printf(s);
#endif
}
#endif
#ifdef MOD
/* This function handles the interface between the BBS and the UU
decode function. If you add directories or change the ones that
are offered here you need also to make changes in several other
places to allow your changes to function. The lines or files that
require changes are indicated with the comment 'change this too'.
As always if you have trouble getting what you want from this mod
let me know and I'll be happy to help. It should not be at all
difficult to add as many directories as you want. This portion of
mod is based on EXTRACT?.MOD which was based on EXTRMSG.MOD.
Birdhunter (1@3451)
AlleyKat (1@8352)
MOD Version only. */
void extract_out(char *b, long len, char *title)
{
char s[MAXPATH],ch=26,ch1;
int i,ret;
int transfer=0,uued=0,quit=0,append=0;
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
/* do not alter these next few lines.*/
npr("\r\n1 UU.MOD, version %s, dated %s.0\r\n",
UU_VER_NO,UU_DATE);
npr(" 2by Jim Wire @3950, @139500\r\n");
/* Thank you.*/
printfile("UU1.MSG"); /* Change this file too */
npr("\r\n2Which (1-7,Q) : "); /* Change this too */
ch1=onek("1234567Q"); /* Change this too */
switch(ch1) {
case '1':
strcpy(s,"..\\EXTRACT\\MAIL\\"); /* directory */
strcpy(in_ext,".MSG"); /* default file extension */
break;
case '2':
strcpy(s,"..\\EXTRACT\\FEEDBACK\\"); /* directory */
strcpy(in_ext,".FBK"); /* default file extension */
break;
case '3':
strcpy(s,"D:\\DLOADS\\MODS\\"); /* directory */
strcpy(in_ext,".MOD"); /* default file extension */
transfer=1; /* a transfer directory */
break;
case '4':
strcpy(s,"D:\\DLOADS\\WWIVMODN\\"); /* directory */
strcpy(in_ext,".MOD"); /* default file extension */
transfer=1; /* a transfer directory */
break;
case '5':
strcpy(s,syscfg.gfilesdir); /* directory */
strcpy(in_ext,".MSG"); /* default file extension */
case '6':
strcpy(s,syscfg.datadir); /* directory */
strcpy(in_ext,".MSG"); /* default file extension */
break;
case '7':
sprintf(s,"..\\EXTRACT\\LOAD\\"); /* directory */
strcpy(in_ext,".UUE"); /* default file extension */
break;
case 'Q':
npr("\n\r7Extract aborted.\r\n\r\n");
return;
}
do {
npr("\r\n1Save under what filename? ");
ret=get_name(s,in_ext);
if(ret==3)
return;
if(ret==2) {
append=1;
ret=0;
}
fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
strcpy(out_path,in_path);
if((strcmp(in_ext,".UUE")==0) && (ret==0))
uued=1;
} while ((!hangup) && (ret!=0));
if(!hangup) {
i=open(in_path,O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
if(i<0) {
npr("\n\r6Unable to get a handle for %s.0\r\n",in_path);
return;
}
if(append)
lseek(i,-1L,SEEK_END);
else
lseek(i,0L,SEEK_END);
write(i,title,strlen(title));
write(i,"\r\n",2);
write(i,(void *)b,len);
write(i,&ch,1);
close(i);
sprintf(s,"%s%s",in_drive,in_dir);
npr("\r\n1File %s written",in_path);
if(uued==1) {
npr("\r\n2Decode the file? (y/N) ");
if(yn())
decd();
} else {
npr("\r\n2Compress the file? (y/N) ");
if(yn()) {
compress();
delete_file(in_path);
}
}
if(transfer==1) {
npr("\r\n2//UPLOAD all the files in %s? (y/N) ",s);
if(yn()) {
for (i=0; (i<64) && (udir[i].subnum>=0) && (!quit); i++) {
if(strcmp(s,(directories[udir[i].subnum].path))==0) {
npr("\r\n1Now //UPLOADing files in %s.0\r\n",s);
uploadall(udir[i].subnum);
}
}
} else {
npr("\r\n2//UPLOAD the file %s? (y/N) ",out_path);
if(yn()) {
fnsplit(out_path,in_drive,in_dir,in_file,in_ext);
for (i=0; (i<64) && (udir[i].subnum>=0) && (!quit); i++) {
if(strcmp(s,(directories[udir[i].subnum].path))==0) {
curdir=udir[i].subnum;
sprintf(s,"%s%s",in_file,in_ext);
npr("\r\n1Now //UPLOADing %s.0\r\n",s);
upload_file(s,curdir,"");
}
}
}
}
}
}
topscreen(); /* added by ED */
farfree(b);
}
/* This function handles the interface between the BBS and the UU
encode function. It allows you to choose from a list of files in
a single directory or load a file from anywhere. If demand warrants
I'll add more directories to choose from. Once selected the file
can be encoded and or edited.
MOD Version only. */
void loadfile()
{
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char out_drive[MAXDRIVE];
char out_dir[MAXDIR];
char out_file[MAXFILE];
char out_ext[MAXEXT];
char du_drive[MAXDRIVE];
char du_dir[MAXDIR];
char du_file[MAXFILE];
char du_ext[MAXEXT];
int in_flags;
int choose,f1,i=1;
char s[MAXPATH],s1[MAXPATH],*sss;
struct ffblk ff;
/* do not alter these next few lines.*/
npr("\r\n1 UU.MOD, version %s, dated %s.0\r\n",
UU_VER_NO,UU_DATE);
npr(" 2by Jim Wire @3950, @139500\r\n");
/* Thank you.*/
npr("\r\n2Choose from list of available files? (Y/n) ");
if(ny()) {
sprintf(s,"..\\EXTRACT\\LOAD\\");
fnsplit(s,in_drive,in_dir,du_file,du_ext);
npr("\r\n1Default directory is %s.",in_dir);
npr("\r\n2Change directory? (y/N) ");
if(yn()) {
npr("\r\n2New //LOAD directory? (ending \\ required) 1");
input(in_path,MAXPATH);
fnsplit(in_path,in_drive,in_dir,du_file,du_ext);
}
fnmerge(in_path,in_drive,in_dir,"","");
sprintf(s,"%s*.*",in_path);
f1=findfirst(s,&ff,0);
if(f1) {
npr("\r\n6No files available.0\r\n");
return;
}
npr("\r\n1Available files:\r\n");
while (f1==0) {
if(i==5) {
npr("1%-12s",ff.ff_name);
i=1;
} else {
npr("1%-17s",ff.ff_name);
++i;
}
f1=findnext(&ff);
}
if(i !=1)
nl();
npr("\r\n2Filename? 1");
input(s,12);
if(s[0]) {
fnsplit(s,du_drive,du_dir,in_file,in_ext);
} else {
npr("\n\r7//LOAD Aborted.");
return;
}
} else {
npr("\n\r2Filename? 1");
input(s,80);
fnsplit(s,in_drive,in_dir,in_file,in_ext);
}
fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
if(strcmp(in_ext,".UUE")!=0) {
npr("\r\n2Encode the file? ");
if(yn()) {
nl();
fnsplit(in_path,out_drive,out_dir,out_file,out_ext);
strcpy(out_ext, ".UUE");
npr("\r\n2Use TEMP directory? ");
if(ny()) {
sprintf(s,"%s",syscfg.tempdir);
fnsplit(s,out_drive,out_dir,du_file,du_ext);
}
fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
encd();
strcpy(in_path,out_path);
}
}
npr("\r\n2Allow editing? (y/N) ");
if(yn())
load_workspace(in_path,0);
else
load_workspace(in_path,1);
topscreen();
}
/* Gets a name for the file to be extracted from the user. Checks for the
existance of that file and offers the user a series of choices if it is
already there.
MOD Version only. */
int get_name(char *path, char *ext)
{
char s[MAXPATH],resp[3],ch1;
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
int in_flags;
char du_drive[MAXDRIVE];
char du_dir[MAXDIR];
char du_file[MAXFILE];
char du_ext[MAXEXT];
fnsplit(path,in_drive,in_dir,du_file,du_ext);
input(s,12);
in_flags=fnsplit(s,du_drive,du_dir,in_file,in_ext);
if(!(in_flags & FILENAME))
return(0);
if(!(in_flags & EXTENSION))
strcpy(in_ext,ext);
fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
if(exist(in_path)) {
npr("\r\n6%s already exists. 0\r\n",in_path);
printfile("UU2.MSG");
npr("\r\n2Which (A,N,O,Q) : ");
ch1=onek("QOAN");
nl();
switch(ch1) {
case 'Q':
return(3);
case 'N':
return(1);
case 'A':
return(2);
case 'O':
npr("\r\n2Do you want to overwrite %s? (Y/N) ",in_path);
scanf("%s",resp);
if((resp[0]!='Y') && (resp[0]!='y'))
return(1);
delete_file(in_path);
return(0);
default:
npr("\r\nAborting");
return(3);
}
} else
return(0);
}
/* This function was added for the //MASTER mod and several others. It
provides backwards compatability.
MOD Version only. */
void compress1(char *fn, char *path)
{
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char du_drive[MAXDRIVE];
char du_dir[MAXDIR];
char du_file[MAXFILE];
char du_ext[MAXEXT];
fnsplit(fn,du_drive,du_dir,in_file,in_ext);
fnsplit(path,in_drive,in_dir,du_file,du_ext);
fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
compress();
}
/* This function compresses the file and removes the source file if
compression was successful. If the system has ZIP as the default
archive extension adds a comment to the ZIP. It receives as input
the file name and path. It is also used by several of my other mods.
If you already have a void compress(char *fn, char *dir) in your BBS
the other one can safely be removed.
MOD Version only. */
void compress()
{
char s[161];
int ret;
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char out_ext[MAXEXT];
npr("2Now compressing %s.\r\n",in_path);
fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
sprintf(out_ext,".%s",syscfg.arcs[0].extension);
fnmerge(out_path,in_drive,in_dir,in_file,out_ext);
if(exist(out_path)) {
npr("\r\n6The file %s already exists.",out_path);
npr("\r\n2Alter contents? (y/N) ");
if(!yn())
return;
}
stuff_in(s,syscfg.arcs[0].arca,out_path,in_path,"","","");
ret=do_remote(s,0);
if(ret == 0) {
delete_file(in_path);
if(strcmp(out_ext,".ZIP") ==0)
comment();
}
topscreen();
}
/* This function adds a comment to a ZIPped file.
MOD Version only. */
/* Ed O'Brien #1 @7350 */
void comment()
{
char s1[161];
npr("2Adding comment to %s.\r\n0",out_path);
sprintf(s1,"PKZIP -z -k %s < %sZIPCOMNT.MSG",out_path,syscfg.gfilesdir);
run_external(s1);
nl();
nl();
}
#endif
/* Based on Waynes npr function. This puts the information passed it into
the file passed. */
void fpr(FILE *out, char *fmt, ...)
{
va_list ap;
char s[512];
va_start(ap, fmt);
vsprintf(s, fmt, ap);
va_end(ap);
fprintf(out,s);
count+=strlen(s);
}
/* This function passes back the location of the specified character in the
string it is passed. If you already have int find_dot (char *fn, char ch)
in your bbs, you will need to remove it and chaange all calls to it.
The calls now require the search character be included in the call.
Example:
dot=find_dot(sig,'.');
will return the location of the character '.' in the string sig. */
int find_dot (char *fn, char ch)
{
char *ptr;
int dot;
ptr=strchr(fn,ch);
dot=ptr-fn;
if(dot<=0)
dot=0;
return(dot);
}
/* This function sets up the segment numbers and file names for multi-segment
files, both new and old format. */
char *forjon(char *ss, int x)
{
char temp[12],s[12],s1[12];
int len;
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
fnsplit(ss,in_drive,in_dir,in_file,in_ext);
sprintf(temp,"%d",segs);
len=strlen(temp);
sprintf(s,"%d",x);
while(strlen(s) < 8-strlen(in_file)) {
strrev(s);
strcat(s,"0");
strrev(s);
}
strcpy(temp,in_file);
if(strlen(in_file)+len >= 8){
strcpy(s1,strrev(strrev(temp)+len-(8-strlen(temp))));
strcpy(temp,s1);
}
sprintf(s1,"%s%s",temp,s);
return(s1);
}
/* This function reads four encoded characters from the input file and
decodes them to produce three 8 bit characters. The three characters
are then written to the output file. */
void decout(char *p, FILE *f,int n)
{
int c1, c2, c3;
c1 =((p[0] - 0x20) & 0x3f) << 2 | ((p[1] - 0x20) & 0x3f) >> 4;
c2 =((p[1] - 0x20) & 0x3f) << 4 | ((p[2] - 0x20) & 0x3f) >> 2;
c3 =((p[2] - 0x20) & 0x3f) << 6 | ((p[3] - 0x20) & 0x3f);
if(n >= 1)
putc(c1, f);
if(n >= 2)
putc(c2, f);
if(n >= 3)
putc(c3, f);
count += n;
}
/* This function reads a line from the input file. These lines are passed
to the decout function in groups of 4 characters where they are decoded
and written to the output file. */
void decode(FILE *in, FILE *out)
{
char *bp, s[81], s1[81];
int n;
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char out_drive[MAXDRIVE];
char out_dir[MAXDIR];
char out_file[MAXFILE];
char out_ext[MAXEXT];
fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
for (;;) {
if((fgets(buf, sizeof buf, in) == NULL)
|| (strncmp(buf,"uu end segment ", 15)==0)
|| (strncmp(buf,"sum ", 4)==0)) {
if(strncmp(buf, "sum ", 4) == 0)
++segs;
if(seg==segs) {
#ifdef MOD
npr("\r\n6Short file.0\r\n");
return;
#else
printf("Short file\n");
exit(10);
#endif
}
++seg;
if(uu_type == 0)
sprintf(s1,"%s%d",out_file,seg);
else
strcpy(s1,forjon(out_path,seg));
fnmerge(s,out_drive,out_dir,s1,in_ext);
if((in = fopen(s, "r")) == NULL) {
#ifdef MOD
npr("\r\n6Cant open %s.0\r\n",s);
return;
#else
perror(s);
exit(1);
#endif
}
fseek(in, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, in) == NULL) {
#ifdef MOD
npr("\r\n6No begin line.0\r\n");
return;
#else
fprintf(stderr, "No begin line.\n");
exit(3);
#endif
}
if(((strncmp(buf, "begin ", 6) == 0)
&& (uu_type == 1))
|| ((strncmp(buf, "section ", 8) == 0)
&& (uu_type == 0)))
break;
}
#ifdef MOD
npr(" %s to produce %s.\n",s,out_file);
#else
printf(" %s to produce %s.\n",s,out_file);
#endif
fgets(buf, sizeof buf, in);
}
n = ((buf[0] - 0x20) & 0x3f);
if(n <= 0)
break;
bp = &buf[1];
while (n > 0) {
decout(bp, out, n);
bp += 4;
n -= 3;
}
}
}
/* This function calls the other fuctions required to perform the decoding
of the file. It is passed the file name and path for the input file and
hands that information off to the other functions. */
int decd()
{
FILE *in, *out;
struct ftime ft;
char sig[81], sig1[81];
char resp[81], s[81], s1[81];
long in_size, out_size;
int temp, dot, ret;
int x, x1=0;
char ft1[3];
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char out_drive[MAXDRIVE];
char out_dir[MAXDIR];
char out_file[MAXFILE];
char out_ext[MAXEXT];
char du_drive[MAXDRIVE];
char du_dir[MAXDIR];
fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
sig[0]=0;
if((in = fopen(in_path, "r")) == NULL) {
perror(in_path);
return(1);
}
fseek(in, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, in) == NULL) {
fprintf(stderr, "No section line\n");
return(3);
}
if(strncmp(buf, "section ", 6) == 0)
break;
}
(void)sscanf(buf, "section %d of %d uu", &seg, &segs);
fseek(in, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, in) == NULL) {
#ifdef MOD
npr("No signature line\r\n");
npr("Switching to old multi-segment file format.\r\n");
#else
printf("No signature line\n");
printf("Switching to old multi-segment file format.\n");
#endif
uu_type=0;
break;
}
if(strncmp(buf, "File signature :",16) == 0) {
strcpy(sig,buf+16);
break;
}
}
if(sig[0]) {
dot=find_dot(sig,'/');
strcpy(sig1,sig);
strrev(sig1);
ft.ft_month=atoi(strrev(sig1+strlen(sig1)-dot));
strcpy(sig,sig+dot+1);
dot=find_dot(sig,'/');
strcpy(sig1,sig);
strrev(sig1);
ft.ft_day=atoi(strrev(sig1+strlen(sig1)-dot));
strcpy(sig,sig+dot+1);
dot=find_dot(sig,' ');
strcpy(sig1,sig);
strrev(sig1);
ft.ft_year=atoi(strrev(sig1+strlen(sig1)-dot));
ft.ft_year=ft.ft_year-60;
strcpy(sig,sig+dot+1);
dot=find_dot(sig,':');
strcpy(sig1,sig);
strrev(sig1);
ft.ft_hour=atoi(strrev(sig1+strlen(sig1)-dot));
strcpy(sig,sig+dot+1);
dot=find_dot(sig,':');
strcpy(sig1,sig);
strrev(sig1);
ft.ft_min=atoi(strrev(sig1+strlen(sig1)-dot));
strcpy(sig,sig+dot+1);
dot=find_dot(sig,' ');
strcpy(sig1,sig);
strrev(sig1);
ft.ft_tsec=atoi(strrev(sig1+strlen(sig1)-dot));
strcpy(sig,sig+dot+1);
in_size=atol(sig);
}
fseek(in, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, in) == NULL) {
fprintf(stderr, "No begin line\n");
return(3);
}
if(strncmp(buf, "begin ", 6) == 0)
break;
}
(void)sscanf(buf, "begin %o %s", &mode, s1);
if(!out_file_specified)
fnsplit(s1,du_drive,du_dir,out_file,out_ext);
fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
if(segs > 1) {
#ifdef MOD
npr("Joining %d segments to make %s.\r\n\n",segs,out_file);
#else
printf("Joining %d segments to make %s.\n\n",segs,out_file);
#endif
for(x = seg; x < segs+1 ; ++x ) {
strcpy(s1,forjon(in_path,x));
fnmerge(s,in_drive,in_dir,s1,in_ext);
if(!exist(s)) {
#ifdef MOD
npr("Can't find %s and don't know how to make it.\r\n",s);
#else
printf("Can't find %s and don't know how to make it.\n",s);
#endif
x1=1;
}
}
if(x1 == 1)
return(8);
}
if(exist(out_path)) {
#ifdef MOD
npr("\r\nDo you want to overwrite %s? (Y/N) ",out_path);
#else
printf("\r\nDo you want to overwrite %s? (Y/N) ",out_path);
#endif
scanf("%s",resp);
if((resp[0]!='Y') && (resp[0]!='y'))
return(7);
}
if(segs > 1)
strcpy(s1,forjon(in_path,seg));
else
strcpy(s1,in_file);
fnmerge(s,in_drive,in_dir,s1,in_ext);
#ifdef MOD
npr("\r\nDECODING %s to produce %s%s.\r\n",s,out_file,out_ext);
#else
printf("\r\nDECODING %s to produce %s%s.\r\n",s,out_file,out_ext);
#endif
out = fopen(out_path, "w+b"); /* Binary file */
if(out == NULL) {
perror(out_path);
return(4);
}
decode(in, out);
fclose(out);
temp=open(out_path,O_RDONLY);
if(temp<=0) {
perror(out_path);
return(1);
}
if(sig[0]) {
out_size=filelength(temp);
if(out_size != in_size) {
fprintf(stderr, "File sizes differ.\n");
return(8);
}
setftime(temp,&ft);
}
close(temp);
_chmod(out_path,1,0);
#ifdef MOD
npr("\r\n1Success.");
npr("\r\n2Delete the UUE file(s)? (y/N)");
if(yn()) {
#endif
if((segs > 1) && (out_file_specified!=1)) {
for(x = 1; x < segs+1 ; ++x ) {
if(uu_type == 0)
sprintf(s1,"%s%d",out_file,x);
else
strcpy(s1,forjon(in_path,x));
fnmerge(s,in_drive,in_dir,s1,in_ext);
#ifdef MOD
npr("Deleting %s.\n",s);
#else
printf("Deleting %s.\n",s);
#endif
delete_file(s);
}
} else {
#ifdef MOD
npr("Deleting %s.\n\n",in_path);
#else
printf("Deleting %s.\n\n",in_path);
#endif
delete_file(in_path);
}
#ifdef MOD
}
npr("\r\n2Compress the file %s? ",out_path);
if(yn())
compress();
#endif
return(0);
}
/* This function takes three eight bit characters and encodes them into
four characters. All four characters which can be displayed using 7
bits and are above 20 hex. The four characteres are written to the
output file individually.
p[0] p[1] p[3]
[0000 0000] [1111 1111] [2222 2222]
(1111 1122) (2222 3333) (3344 4444)
c1() c2() c3() c4() */
void encout(char *p, FILE *f)
{
int c1, c2, c3, c4;
c1 = (p[0] >> 2) & 0x3f; /* first 6 bits of p[0] */
c2 = (p[0] << 4) & 0x30 | (p[1] >> 4) & 0x0f;/* last 2 p[0] first 4 p[1] */
c3 = (p[1] << 2) & 0x3c | (p[2] >> 6) & 0x03;/* last 4 of p[1] first 2 p[2] */
c4 = (p[2] & 0x3f); /* last 6 bits if p[2] */
putc(((c1) ? ((c1) & 0x3f) + 0x20 : 0x60), f);
putc(((c2) ? ((c2) & 0x3f) + 0x20 : 0x60), f);
putc(((c3) ? ((c3) & 0x3f) + 0x20 : 0x60), f);
putc(((c4) ? ((c4) & 0x3f) + 0x20 : 0x60), f);
count += 4;
}
/* This function reads blocks of 45 characters from the input file. These
blocks are passed to the encout function in groups of 3 characters where
they are encoded and written to the output file. */
int encode(FILE *in, FILE *out, char *sig)
{
int i, n;
char s[81], s1[81];
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char out_drive[MAXDRIVE];
char out_dir[MAXDIR];
char out_file[MAXFILE];
char out_ext[MAXEXT];
fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
for (;;) {
n = fread(buf, 1, 45, in);
putc(((n) ? ((n) & 0x3f) + 0x20 : 0x60), out);
++count;
for (i=0; i<n; i += 3)
encout(&buf[i], out);
putc('\n', out);
count = count + 2;
if((count >=size) && (segs !=1)) {
fpr(out, "uu end segment %d of %d.\n",seg,segs);
fclose(out);
strcpy(s1,forjon(out_path,seg));
sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
_chmod(s,1,0);
count=0;
++seg;
strcpy(s1,forjon(out_path,seg));
sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
#ifdef MOD
npr(" %s%s to produce %s.\r\n",in_file,in_ext,s);
#else
printf(" %s%s to produce %s.\r\n",in_file,in_ext,s);
#endif
if((out = fopen(s, "w+")) == NULL) {
#ifdef MOD
npr("\r\n6Cant open %s.0\r\n",s);
return(4);
#else
perror(s);
exit(4);
#endif
}
fpr(out,"section %d of %d uu %s of file %s%s by J.L.W\n",
seg,segs,"1.12",in_file,in_ext);
fpr(out, sig);
fpr(out,"File name : %s%s\n",s1,out_ext);
fpr(out, "begin %o %s%s\n", mode, in_file,in_ext);
}
if(n <= 0)
break;
}
return(0);
}
/* This function calls the other fuctions required to perform the encoding
of the file. It is passed the file name and path for the input file and
hands that information off to the other functions. */
void encd()
{
FILE *in, *out;
struct stat sbuf;
struct ftime ft;
char resp[81], s[81], s1[81], s2[12], sig[81];
int temp, x, x1=0;
long in_size, out_size;
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char out_drive[MAXDRIVE];
char out_dir[MAXDIR];
char out_file[MAXFILE];
char out_ext[MAXEXT];
fnsplit(in_path,in_drive,in_dir,in_file,in_ext);
fnsplit(out_path,out_drive,out_dir,out_file,out_ext);
temp=open(in_path,O_RDONLY);
if(temp<=0) {
#ifdef MOD
npr("\r\n6Cant open %s.0\r\n",in_path);
return;
#else
perror(in_path);
exit(1);
#endif
}
getftime(temp,&ft);
in_size = filelength(temp);
close(temp);
out_size = in_size/45;
out_size = out_size*63;
out_size = out_size+(173*(in_size/size));
if((in = fopen(in_path, "rb")) == NULL) {
#ifdef MOD
npr("\r\n6Cant open %s.0\r\n",in_path);
return;
#else
perror(in_path);
exit(1);
#endif
}
if(out_size >=size) {
segs = (out_size/size)+1;
sprintf(s,"%d",segs);
if(strlen(s) > 8) {
#ifdef MOD
npr("Who are you kidding? %d files? That is rediculous!",segs);
return;
#else
printf("Who are you kidding? %d files? That is rediculous!",segs);
exit(11);
#endif
}
if(strlen(s) > 1) {
#ifdef MOD
npr("Who are you kidding? %d files? That seems a little rediculous!",segs);
npr("I'll do it for you though Jon; but who is going to send %d messages?",segs);
#else
printf("Who are you kidding? %d files? That seems a little rediculous!",segs);
printf("I'll do it for you though Jon; but who is going to send %d messages?",segs);
#endif
}
#ifdef MOD
npr("Dividing %s into %d segments.\n\n",in_path,segs);
#else
printf("Dividing %s into %d segments.\n\n",in_path,segs);
#endif
for(x = seg; x < segs+1 ; ++x ) {
strcpy(s1,forjon(out_path,x));
sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
if(exist(s)) {
printf(" The file %s already exists.\n",s);
x1=1;
}
}
if(x1) {
#ifdef MOD
npr("\nDo you want to overwrite? %s (Y/N) ",s);
#else
printf("\nDo you want to overwrite? %s (Y/N) ",s);
#endif
scanf("%s",resp);
if((resp[0]!='Y') && (resp[0]!='y')) {
#ifdef MOD
npr("Choosing not to overwrite, aborting.\r\n");
return;
#else
printf("Choosing not to overwrite, aborting.\n");
exit(7);
#endif
}
}
for(x = seg; x < segs+1 ; ++x ) {
strcpy(s1,forjon(out_path,x));
sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
delete_file(s);
}
strcpy(s1,forjon(out_path,seg));
sprintf(s,"%s%s%s%s",out_drive,out_dir,s1,out_ext);
} else {
strcpy(s1,in_file);
sprintf(s,"%s%s%s%s",out_drive,out_dir,in_file,out_ext);
if(exist(s)) {
#ifdef MOD
npr("\nDo you want to overwrite? %s (Y/N) ",s);
#else
printf("\nDo you want to overwrite? %s (Y/N) ",s);
#endif
scanf("%s",resp);
if((resp[0]!='Y') && (resp[0]!='y')) {
#ifdef MOD
npr("Choosing not to overwrite, aborting.\r\n");
return;
#else
printf("Choosing not to overwrite, aborting.\n");
exit(7);
#endif
}
}
}
if((out = fopen(s, "w+")) == NULL) {
#ifdef MOD
npr("\r\n6Cant open %s.0\r\n",s);
return;
#else
perror(s);
exit(4);
#endif
}
if(fstat(fileno(in), &sbuf) < 0 || !isatty(fileno(in)))
mode = 0666 & ~umask(0666);
else
mode = sbuf.st_mode & 0777;
fpr(out,"section %d of %d uu %s of file %s%s by J.L.W\n",
seg,segs,"1.12",in_file,in_ext);
fpr(out,"File name : %s%s\n",s1,out_ext);
sprintf(sig, "File signature : %u/%u/%u %u:%u:%u %ld\n\n",
ft.ft_month, ft.ft_day, ft.ft_year+1980,
ft.ft_hour, ft.ft_min,ft.ft_tsec * 2,in_size);
fpr(out, sig);
fpr(out, "begin %o %s%s\n", mode, in_file,in_ext);
sprintf(s,"%s%s",in_file,in_ext);
#ifdef MOD
npr("\r\nENCODING %s to produce %s%s.\n",s,s1,out_ext);
#else
printf("\r\nENCODING %s to produce %s%s.\n",s,s1,out_ext);
#endif
encode(in, out, sig);
fpr(out, "end\n");
fclose(out);
strcpy(s1,forjon(out_path,seg));
sprintf(s,"%s%s%s%s",out_drive,out_path,s1,out_ext);
_chmod(s,1,0);
}
#ifndef MOD
/* This function locates and loads the UU config file. It is not currently
called by the mod version of UU; but may soon be. */
int uudefault() /* EXE only */
{
FILE *cfg;
int cfgerror=0;
char errm[81];
char in_ext[MAXEXT];
char out_ext[MAXEXT];
if(exist(home_path)) {
if((cfg = fopen(home_path, "r")) == NULL) {
strcpy(errm,"Can't seem to access my cfg file");
cfgerror |= 1;
perror(home_path);
return(1);
}
fseek(cfg, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, cfg) == NULL) {
fprintf(stderr, "No in ext line\n");
cfgerror |= 2;
return(3);
}
if(strncmp(buf, "in ext:", 7) == 0)
break;
}
(void)sscanf(buf, "in ext:%s", &in_ext);
fseek(cfg, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, cfg) == NULL) {
fprintf(stderr, "No out ext line\n");
cfgerror |= 4;
return(3);
}
if(strncmp(buf, "out ext:", 8) == 0)
break;
}
(void)sscanf(buf, "out ext:%s", &out_ext);
fseek(cfg, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, cfg) == NULL) {
fprintf(stderr, "No output file size line\n");
cfgerror |= 8;
return(3);
}
if(strncmp(buf, "out size:", 9) == 0)
break;
}
(void)sscanf(buf, "out size:%ld", &size);
fseek(cfg, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, cfg) == NULL) {
fprintf(stderr, "No output file line count line\n");
cfgerror |= 16;
return(3);
}
if(strncmp(buf, "out line:", 9) == 0)
break;
}
(void)sscanf(buf, "out line:%d", &line);
} else {
#ifdef MOD
npr("can't find my .cfg file.\r\n");
#else
printf("can't find my .cfg file.\n");
#endif
}
return(1);
}
/* This function locates and displays the UU help file. It is not currently
called by the mod version of UU; but may soon be. */
int help() /* EXE only */
{
FILE *hlp;
int hlperror=0;
char errm[81];
char resp[3];
if(exist(home_path)) {
if((hlp = fopen(home_path, "r")) == NULL) {
strcpy(errm,"Can't seem to access my help file");
hlperror |= 1;
perror(home_path);
return(hlperror);
}
fseek(hlp, 0, SEEK_SET);
for (;;) {
if(fgets(buf, sizeof buf, hlp) == NULL) {
fprintf(stderr, "Unexpected end of file.\n");
hlperror |= 2;
return(3);
}
if(strncmp(buf, "end help", 8) == 0)
break;
else if(strncmp(buf, "page help", 8) == 0) {
#ifdef MOD
npr("More? (Y/N) ");
#else
printf("More? (Y/N) ");
#endif
scanf("%s",resp);
if((resp[0]!='Y') && (resp[0]!='y'))
return(0);
clrscr();
sprintf(errm,"UU.EXE version %s by Jim Wire\r\n",UU_VER_NO);
printf(errm);
}
else
#ifdef MOD
npr(buf);
#else
printf(buf);
#endif
}
} else {
#ifdef MOD
npr("can't find my .hlp file.\r\n");
#else
printf("can't find my .hlp file.\n");
#endif
}
return(1);
}
/* Stolen from WWIV, this little guy checks for the file */
int exist(char *s) /* EXE only */
{
int f;
f=open(s,O_RDONLY | O_BINARY);
close(f);
if(f>0) {
_chmod(s,1,0);
return(1);
} else
return(0);
}
int main(int argc, char *argv[]) /* EXE only */
{
char s[81],s1[12],cmd[3],resp[81];
int res;
char in_drive[MAXDRIVE];
char in_dir[MAXDIR];
char in_file[MAXFILE];
char in_ext[MAXEXT];
char out_drive[MAXDRIVE];
char out_dir[MAXDIR];
char out_file[MAXFILE];
char out_ext[MAXEXT];
int out_flags=0;
char home_drive[MAXDRIVE];
char home_dir[MAXDIR];
char home_file[MAXFILE];
char home_ext[MAXEXT];
clrscr();
sprintf(s,"UU.EXE version %s by Jim Wire\r\n",UU_VER_NO);
printf(s);
fnsplit(argv[0],home_drive,home_dir,home_file,home_ext);
fnmerge(home_path,home_drive,home_dir,home_file,".CFG");
uudefault();
if(argc >= 2) {
strcpy(s,argv[1]);
strcpy(cmd,s+strlen(s)-1);
}
if((argc < 3) || ((strcmp(cmd,"H")==0)
|| (strcmp(cmd,"h")==0) || (strcmp(cmd,"?")==0))) {
fnmerge(home_path,home_drive,home_dir,home_file,".HLP");
help();
return(0);
} else {
fnsplit(argv[2],in_drive,in_dir,in_file,in_ext);
fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
if((strcmp(cmd,"E")==0) || (strcmp(cmd,"e")==0)) {
if(argc == 4) {
out_flags=fnsplit(argv[3],out_drive,out_dir,out_file,out_ext);
if(!(out_flags & DRIVE))
strcpy(out_drive,in_drive);
if(!(out_flags & DIRECTORY) && (strcmp(out_drive,in_drive) !=0))
strcpy(out_dir,in_dir);
if(!((out_flags & FILENAME) && (out_flags & EXTENSION))) {
strcpy(out_file,in_file);
strcpy(out_ext,".UUE");
}
} else {
out_flags=fnsplit(in_path,out_drive,out_dir,out_file,out_ext);
strcpy(out_ext,".UUE");
}
if(strcmp(out_ext,".UUE") !=0) {
printf("Allow command line to override default? (Y/N)");
scanf("%s",resp);
if((resp[0]!='Y') && (resp[0]!='y'))
strcpy(out_ext,".UUE");
}
fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
res=encd();
}
if((strcmp(cmd,"D")==0) || (strcmp(cmd,"d")==0)) {
if(argc == 4) {
out_flags=fnsplit(argv[3],out_drive,out_dir,out_file,out_ext);
if(!(out_flags & DRIVE))
strcpy(out_drive,in_drive);
if(!(out_flags & DIRECTORY) && (strcmp(out_drive,in_drive) !=0))
strcpy(out_dir,in_dir);
if((out_flags & FILENAME) && (out_flags & EXTENSION)) {
out_file_specified=1;
fnmerge(out_path,out_drive,out_dir,out_file,out_ext);
} else
fnmerge(out_path,out_drive,out_dir,in_file,in_ext);
} else
fnmerge(in_path,in_drive,in_dir,in_file,in_ext);
res=decd();
}
if(res==0) {
printf("Success.\r\n");
}
}
return(res);
}
#endif