#ifdef DOCUMENTATION Title nftupd Updates file from remote computer to local computer Index nftupd Updates file from remote computer to local computer Usage .s.nf nup node::[uic]infile outfile.spec Description nftupd will open a file remotely, a file locally and copy from the remote file to the local file. Both files must have been created. To use nftupd, you must supply arguments in the form of: Node::[XX,XX]input.ext output.ext (e.g. DEVSYS::[40,40]options.dat new.dat) The example above would open a file remotely on the devsys computer called options.dat and copy that file to a file called new.dat on whatever computer you are using. Implementation Details nftupd does remote file access on computer requested (node name). It opens remote file requested in read mode. If then opens local file requested in append mode. It uses rgetb to get one block of data from remote file and put it into a buffer. If then used fputb to put this same data into a buffer for the local file (thus copying the data to the local output file). The block number for the input (rgetb) and output (fputb) is increased each time by the number of blocks being read in (BLKSIZ). The input and output continues until the physical end of file is reached (-10), at which time both files are closed and the program exits. If any errors are encountered, a message is sent out through tmsg. #endif #include #include #include #include #define BUFSIZ 15 /* maximum xfr across net is 8k */ char buf[BUFSIZ*512]; /* read-write buffer */ NIOV *fd1; /* Input file channel */ FILE *fd2; /* Output file channel */ extern OPNSTS $rstat; /* statistics for remote file */ extern unsigned $$stbk[]; /* statistics block for local file */ extern int $$ferr; /* file error */ extern int $$nerr; /* network error */ main(argc,argv) char *argv[]; { int blknum; FATRB *ap; /* attributes pointer */ int rmtsiz; /* remote file size */ int lclsiz; /* local file size */ int xfrsiz; /* size of current transfer */ if(argc != 3) { /* check for valid argument input */ tmsg('F',"usage: nup \n"); exit(1); } if((fd1 = fopnxn(argv[1], "rn", 0, 0)) == NULL){ /* remote file open */ tmsg('F', "can't open input file %s ferr %o nerr %o\n", argv[1], $$ferr, $$nerr); exits(4); /* exit with error */ } ap = &$rstat.att; /* point remote file attributes */ rmtsiz = ap->f_efbk[1] - 1; /* end of file on remote */ #ifdef DEBUG tmsg('M', "typ %3.3o att %3.3o rsiz %d hibk|%d|%d| efbk|%d|%d| ffby %d\n", ap->f_rtyp, ap->f_ratt, ap->f_rsiz, ap->f_hibk[0], ap->f_hibk[1], ap->f_efbk[0], ap->f_efbk[1], ap->f_ffby); #endif if((fd2 =fopenx(argv[2],"m", 0, 0)) == NULL){ /* local file open */ tmsg('F',"can't open file %s\n", argv[2]); exit(4); /* exit with error */ } lclsiz = $$stbk[3]; /* local file allocation */ if (lclsiz < rmtsiz) { tmsg('W', "local file smaller than remote, update will be incomplete\n"); rmtsiz = lclsiz; /* rmtsiz is the amount to copy */ } blknum=1; /* input & output start at block 1 */ for (;;) { if (rmtsiz >= BUFSIZ) xfrsiz = BUFSIZ; else xfrsiz = rmtsiz; rmtsiz -= xfrsiz; if (rgetb(&buf, 512*xfrsiz, blknum, fd1) <= 0) { /* remote get */ if ($$ferr != -10) break; /* physical end of file indicator */ else { tmsg('F',"geterr %o nerr %o\n", $$ferr, $$nerr); exits(4); /* exit with error */ } } if (fputb(&buf, 512*xfrsiz, blknum, fd2) ==0) { /* local put */ tmsg('F', "file write error ferr %o\n", $$ferr & 0377); exits(4); /* exit with error */ } blknum = blknum + xfrsiz; /* increment by num of blocks read */ } /* end for(;;) */ rclose(fd1); /* close input file when done */ fclose(fd2); /* close output file when done */ exits(1); }