home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
microcrn
/
issue_48.arc
/
PPXFER.ARC
/
PPXFER.C
< prev
next >
Wrap
Text File
|
1989-05-16
|
6KB
|
213 lines
/* Support code from Micro Cornucopia Magazine Issue #48
Micro Cornucopia
PO Box 223
Bend, OR 97709 */
#include <io.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <dir.h>
#include <time.h> /* to calculate transfer speeds */
#include "ppxfer.h" /* header file containing appropriate definitions */
dbyte base_plus_two; /* global so output value at BASE+2 doesn't accidentally
get changed */
#define RAISE_HANDSHAKE (outportb(BASE+2, base_plus_two &= ~(1 << 3)))
#define LOWER_HANDSHAKE (outportb(BASE+2, base_plus_two |= (1 << 3)))
#define TESTKEY if (kbhit()) break
/* Prints a byte in binary (for testing): */
void print_binary(dbyte c) {
int i = 7;
do printf("%c", c & (1 << i) ? '1' : '0'); while(i--);
}
/* Set the channel to the "idle" state: */
void idle(void) {
outportb(BASE,0xff); /* all lines high */
/* initialize so everything's an input (handshake is high): */
outportb(BASE+2, (base_plus_two = 0x04));
}
dbyte receive_byte(void) {
dbyte data;
while( ! (inportb(BASE+2) & (1<<3)))
;
data = (inportb(BASE+1) & 0xf8) | (inportb(BASE+2) & 0x07);
outportb(BASE, 0xfe); /* send BYTE RECD signal */
data ^= 0x83; /* flip "inverted" bits */
while( (inportb(BASE+2) & (1<<3)))
;
outportb(BASE, 0xff); /* de-assert BYTE RECD signal */
return data;
}
void send_byte( dbyte data) {
outportb(BASE, data);
LOWER_HANDSHAKE;
while( ! (inportb(BASE+2) & 1)) {
if (inportb(BASE+2) & 2) {
puts("aborted by receiver");
exit(1);
}
TESTKEY;
}
RAISE_HANDSHAKE;
while ( inportb(BASE + 2) & 1) {
if (inportb(BASE+2) & 2) { puts("aborted"); exit(1); }
TESTKEY;
}
}
void send_string( char * string) {
while(*string) {
send_byte(*string);
string++;
}
}
void usage(char * msg) {
puts("\nusage: ppxfer -s file1.ext ...");
puts(" to send files through the parallel port using the special");
puts(" cable configuration, (the list of files can be any length;");
puts(" wildcards may be used in the file name) or:");
puts("ppxfer -sh file1.ext ...");
puts(" to send files and leave the receiver on hold so other");
puts(" files may be sent, or:");
puts("ppxfer -r");
puts(" to receive files.");
puts(msg);
exit(1);
}
void send_file(char * unambiguous_name) {
int i, infile;
unsigned long filesize, readsize;
char buf[30];
dbyte filebuf[BUFSIZE];
long secs_start, secs_end; /* for timing */
if ((infile = open(unambiguous_name,O_RDONLY | O_BINARY )) < 0 ) {
puts("cannot open file to send:");
puts(unambiguous_name);
exit(1);
}
filesize = lseek(infile, 0L, 2); /* find file size */
lseek(infile, 0L, 0); /* reset file pointer to beginning */
ultoa(filesize,buf,10);
idle();
send_byte(ATTN); /* send an escape */
send_string("filename"); send_byte(LDELIMIT);
send_string(unambiguous_name); send_byte(RDELIMIT);
send_byte(LDELIMIT);
send_string(buf); send_byte(RDELIMIT);
printf("sending %-15s size: %s bytes: ", unambiguous_name, buf);
#ifdef TIME
time(&secs_start);
printf("starting time: %d\n", secs_start);
#endif TIME
while((readsize = read(infile, filebuf, BUFSIZE)) > 0 )
#ifdef MASM
send_block(filebuf, readsize);
#else MASM /* if you don't have MASM, you'll have to do it the slow way: */
for (i = 0; i < readsize; i++)
send_byte(filebuf[i]);
#endif MASM
close(infile);
#ifdef TIME
time(&secs_end);
printf("ending time: %d\n", secs_end);
printf("%f Kbytes/sec\n", (filesize/1000)/(secs_end - secs_start));
#endif TIME
}
void receive_files(void) {
char c;
int i,j, outfile;
unsigned long incr, filesize, bytecount, readsize;
char buf[30], filename[30];
dbyte filebuf[BUFSIZE];
idle();
while(1) {
while ( receive_byte() != ATTN )
if (kbhit()) if (getch() == 27) exit(1);
/* hunt for an ESCAPE from the port or the keyboard */
for (i=0; (c = receive_byte()) != LDELIMIT; )
buf[i++] = c;
buf[i] = 0; /* end of control string */
if (strcmp(buf,"end of transaction") == 0) {
puts("end of transaction");
exit(0);
}
if (strcmp(buf,"filename") == 0) {
for (i=0; (c = receive_byte()) != RDELIMIT; )
filename[i++] = c;
filename[i] = 0;
for (i=0; (c = receive_byte()) != LDELIMIT; )
; /* throw away characters until left delimiter */
for (i=0; (c = receive_byte()) != RDELIMIT; )
buf[i++] = c; /* store characters until right delimiter */
buf[i] = 0;
filesize = atol(buf);
printf("receiving %-15s size: %s bytes\n",filename, buf);
if ((outfile = open(filename,
O_WRONLY | O_BINARY | O_CREAT, S_IREAD|S_IWRITE)) < 0 ) {
puts("cannot open output file");
outportb(BASE,0xfd); /* set "abort" line */
switch(errno) {
case ENOENT: puts("path or file name not found"); break;
case EMFILE: puts ("too many open files"); break;
case EACCES: puts ("permission denied"); break;
case EINVACC: puts("invalid access code");
}
exit(1);
}
for (incr = (signed)(filesize - BUFSIZE) > 0 ?
BUFSIZE : filesize, bytecount = 0;
bytecount < filesize;
bytecount += incr,
incr = filesize - bytecount > BUFSIZE ? BUFSIZE
: filesize - bytecount ) {
receive_block(filebuf,incr);
write(outfile, filebuf, incr);
}
close(outfile);
}
}
}
void main(int argc, char * argv[]) {
struct ffblk file_block;
int i, done;
if (argv[1][0] != '-' ||
(argv[1][1] != 's' && argv[1][1] != 'r')) usage("use '-s' or '-r'");
/* receive files: */
if (argv[1][1] == 'r')
receive_files();
/* send files using wildcards: */
if (argv[1][1] == 's' ) {
if (argc < 3) usage("not enough arguments");
for(i = 2; i < argc; i++) {
done = findfirst(argv[i],&file_block,0);
while (!done) {
send_file(file_block.ff_name);
done = findnext(&file_block);
}
}
if (argv[1][2] == 'h')
{ puts("receiver ready for more files"); exit(0); }
send_byte(ATTN);
send_string("end of transaction"); send_byte(LDELIMIT);
}
}