/* setdru -- install setdru1 or setdru2 */ /* copyright 1983-84 Michael M Rubenstein */ /* version 1.3 9 Feb 84 -- eliminated Z80 code */ /* change in run time library only, but version */ /* changed to avoid confusion. */ /* version 1.2 2 Feb 84 -- code modified for distribution */ /* version 1.1 26 Nov 83 -- allowed user numbers up thru 31 for */ /* compatibility with zcpr */ #define NULL 0 #define TRUE 1 #define FALSE 0 /* declaration of structure for fcb */ struct fcb_ { struct { char drive; /* drive number */ char fname[8]; /* file name */ char ftype[3]; /* file type */ char fext; /* file extent */ char filler[3]; } name1, name2; char crec; /* current record */ int rrec; /* random record */ char rovf; /* random record overflow */ }; #define FCB struct fcb_ #define CTLC '\003' #define BUFSIZE (16*1024) struct sdr { char s_fil1[3]; /* jp instruction */ int s_len; /* length of module */ unsigned s_plen; /* length of pgm */ struct { char s_drive, s_user; char s_fname[8]; char s_ftype[3]; } s_file[9]; }; extern FCB dfcb_; extern char dbuff_[]; extern struct sdr sdru1, sdru2; struct { char maxin; char insize; char inline[33]; } inbuf = { 32 }; main() { static struct sdr *sdru; static int integr; static int i, j; static char *s, *t; FCB infcb, outfcb, holdfcb; char buffer[BUFSIZE]; signon(); integr = ask("\nDo you want SETDRU integrated with the program (y or n)? "); sdru = integr ? &sdru2 : &sdru1; for (;;) { if (!askfn("\nTo which program do you want to apply SETDRU? ", &infcb)) return; strncpy(sdru->s_file[0].s_fname, infcb.name1.fname, 11); sdru->s_file[0].s_drive = dfcb_.name1.drive ? dfcb_.name1.drive : (curdsk() + 1); sdru->s_file[0].s_user = '\0'; if (integr) { if (open(&infcb) != 0xff) { filsiz(&infcb); sdru->s_plen = 128 * infcb.rrec; break; } ps("Cannot open\n"); } else { sdru->s_file[0].s_user = askuser(); break; } } if (!askfn("What is the name of the program to be created? ", &outfcb)) return; strncpy(&holdfcb, &outfcb, sizeof(FCB)); strncpy(outfcb.name1.ftype, "$$$", 3); delete(&outfcb); if (make(&outfcb) == 0xff) error("Cannot create file"); for (i = 1; i < 9; ++i) { ps("\nFile "); pn(i); if (!askfn("? ", &dfcb_)) if (i > 1) break; else { i = 0; continue; } strncpy(sdru->s_file[i].s_fname, dfcb_.name1.fname, 11); sdru->s_file[i].s_drive = dfcb_.name1.drive ? dfcb_.name1.drive : (curdsk() + 1); sdru->s_file[i].s_user = askuser(); } for (s = (char *) sdru, i = sdru->s_len; i > 0; s += 128, i -=128) { setdma(s); if (wrseq(&outfcb)) error("Error writing file."); } if (integr) { do { for (s = buffer, i = BUFSIZE; i > 0; s += 128, i -= 128) { setdma(s); if (j = rdseq(&infcb)) break; } for (t = buffer; t < s; t += 128) { setdma(t); if (wrseq(t, &outfcb)) error("Error writing file."); } } while(!j); } close(&outfcb); delete(&holdfcb); strncpy(&outfcb.name2, &holdfcb.name1, sizeof(outfcb.name1)); outfcb.name2.drive = '\0'; if (rename(&outfcb) == 0xff) error("Cannot rename output file."); ps("\nInstallation successful.\n"); } signon() { static char *msg[] = { "Copyright 1983-4 Michael M Rubenstein\n", "SETDRU 1.3 -- set drive and user for specified files in a program\n\n", "Up to 8 (ambiguous) file names may be specified.\n\n", "An input file will match the first matching file name. If it is\n", "ambiguous, the redirection (drive and user) will be used only if the\n", "file cannot be found on the drive specified by the program. If\n", "unambiguous, the file will always be redirected.\n\n", "An output file will match the first unambiguous (only) matching file\n", "name. It will always be redirected.\n\n", "Nonmatching files will not be affected\n\n", "May be installed as a separate program which loads the desired program\n", "or as a modification to the desired program.\n\n", "See SETDRU.DOC for more information.\n\n", "Specify drive letters in the normal manner (B:FILE.TYP). You will be\n", "prompted for user number.\n", NULL }; char **s; for (s = msg; *s != NULL; ++s) ps(*s); } /* ask yes or no */ ask(s) char *s; { for (;;) { ps(s); rdbuf(&inbuf); wrcon('\n'); switch (toupper(inbuf.inline[0])) { case '\r': case '\n': case 'Y': return TRUE; case 'N': return FALSE; case CTLC: exit(); } } } askfn(s, f) char *s; FCB *f; { for (;;) { ps(s); rdbuf(&inbuf); wrcon('\n'); if (inbuf.insize == '\0') return FALSE; inbuf.inline[inbuf.insize] = '\0'; setfcb(inbuf.inline, f); if (f->name1.drive == '\0') f->name1.drive = curdsk() + 1; if (f->name1.fname[0] != ' ') return(TRUE); } } askuser() { static int n; for (;;) { ps("User number? "); rdbuf(&inbuf); wrcon('\n'); if (inbuf.insize == 0) return getusr(); inbuf.inline[inbuf.insize] = '\0'; if ((n = atoi(inbuf.inline)) >=0 && n <= 31) return n; } } pn(n) int n; { if (n > 9) pn(n / 10); wrcon(n % 10 + '0'); } ps(s) char *s; { while (*s) { if (*s == '\n') wrcon('\r'); wrcon(*(s++)); } }