/* * Installation code for REDUCE in the Codemist CSL version. This * code is intended for use with MSDOS, and is compiled with * Zortech C release 3.0 * * Compile with: * ztc -mc -DMS_DOS=1 install.c */ /* * Copyright (C) 1992, Codemist Ltd. * This code has been modelled after suggestions from Jed Marti */ /* Signature: 351e7887 29-Mar-1994 */ /* * Here, right at the top of this program, I give a list of the * files that are to be unpacked. */ typedef struct arch { char *name; int loaded; } arch; static arch archives[] = { {"EXE286.CAR", 0}, /* 0 */ {"EXE386.CAR", 0}, /* 1 */ {"OBJS286.CAR", 0}, /* 2 */ {"SMAL286.CAR", 0}, /* 3 */ {"OBJS386.CAR", 0}, /* 4 */ {"SMAL386.CAR", 0}, /* 5 */ {"SOURCE1.CAR", 0}, /* 6 */ {"SOURCE2.CAR", 0}, /* 7 */ {"SOURCE3.CAR", 0}, /* 8 */ {"SOURCE4.CAR", 0}, /* 9 */ {"GNUPLOT1.CAR", 0}, /* 10 */ {"GNUPLOT2.CAR", 0}, /* 11 */ {"IMG1.CAR", 0}, /* 12 */ {"IMG2.CAR", 0}, /* 13 */ {"DOCS1.CAR", 0}, /* 14 */ {"DOCS2.CAR", 0}, /* 15 */ {"XLOG1.CAR", 0}, /* 16 */ {"XLOG2.CAR", 0}, /* 17 */ {"XMPL1.CAR", 0}, /* 18 */ {"XMPL2.CAR", 0}, /* 19 */ {"README.CAR", 0} /* 20 */ }; #define NARCHIVES (sizeof(archives)/sizeof(archives[0])) #define O_EXE286 0 #define O_EXE386 1 #define O_OBJS286 2 #define O_SMAL286 3 #define O_OBJS386 4 #define O_SMAL386 5 #define O_SOURCE1 6 #define O_SOURCE2 7 #define O_SOURCE3 8 #define O_SOURCE4 9 #define O_GNUPLOT1 10 #define O_GNUPLOT2 11 #define O_IMG1 12 #define O_IMG2 13 #define O_DOCS1 14 #define O_DOCS2 15 #include #include #include #include #include #include #include #include #include #include /* The Zortech C fast screen-output package */ #include /* unbuffered keyboard input etc */ #include /* for mkdir() to create directories */ #include /* so that I can select which drive is current */ #define EXTRACT 1 #define INSTALL 1 static jmp_buf escape_buffer; static void ctrl_c_handler(int n) { longjmp(escape_buffer, 1); } static void show_txt(int row, int col, char *msg); #include "car.c" /* File decompression technology */ #define white_on_blue 0x17 #define white_on_black 0x07 #define black_on_white 0x70 /* * filep(dr, fn) - returns nonzero if drive dr and file name exists, 0 if not. */ static FILE *filep(char *dr, char *fn) { char fname[256]; FILE *fh; sprintf(fname, "%s%s\0", dr, fn); return fopen(fname, "rb"); } /* * There is a smallish area in the middle of the screen that I * actually use here - clear it to the background colour (blue) that * I am using. */ static void clear_work_area() { disp_fillbox(256*white_on_blue + ' ', 7, 11, 18, 68); } static void show_txt(int row, int col, char *msg) { int c, l = col; disp_move(row, col); while ((c = *msg++) != 0) { if (c == '\n') { while (l <= 68) { disp_putc(' '); l++; } disp_move(++row, col); l = col; } else { disp_putc(c); l++; } } } /* * This routine asks the use a question. The question is passed as * MSG and it will ask the user to type in a value. The default * will be provided in VAL, and that will be what is used if the user * just hits ENTER. maxlen indicates the size of the VAL buffer, so * that (with luck) I can avoid overwriting things. The message HELP * is displayed so that the user understands what the question is * supposed to be about. Returns non-zero if user wants to give up. */ static int request_string(int maxlen, char *msg, char *help, char *val, char *dflt) { int i, j, hwm; clear_work_area(); disp_setattr(white_on_black); show_txt(8, 11, msg); show_txt(12, 11, help); disp_setattr(black_on_white); strcpy(val, dflt); show_txt(10, 16, val); hwm = i = strlen(val); disp_move(10, 16+i); disp_flush(); for (;;) { int c = getch(); if (c == 0) c = 0x100 + getch(); /* Extended character */ switch (c) { case 0x03: case 0x1b: /* ^C and ESC */ return 1; case 0x08: /* backspace deletes char before the cursor */ if (i == 0) continue; i--; case 0xff: case 0x100+'S': /* DELete deletes char at cursor */ if (i == hwm) continue; disp_move(10, 16+i); hwm--; for (j=i; j= maxlen) continue; hwm++; for (j=hwm; j>i; j--) val[j] = val[j-1]; val[i] = ' '; disp_move(10, 16+i); for (j=i; j= 0x100) continue; /* Ignore extended chars */ if (i < maxlen) { val[i++] = c; disp_putc(c); disp_flush(); if (i > hwm) hwm = i; } continue; } } } /* * request_char is like request_string, except that the input needed from * the user will be just one character long. The result is dumped into the * first character of VAL. */ static int request_char(char *msg, char *help, char *val) { clear_work_area(); disp_setattr(white_on_black); show_txt(8, 11, msg); show_txt(12, 11, help); disp_setattr(black_on_white); show_txt(10, 16, val); disp_move(10, 16); disp_flush(); for (;;) { int c = getch(); switch (c & 0x7f) { case 0x03: case 0x1b: /* ^C and ESC */ return 1; case '\r': case '\n': /* ENTER */ return 0; case 0x08: case 0x7f: /* backspace and DELete - mapped to blank */ c = ' '; default: c = toupper(c); val[0] = c; disp_move(10, 16); disp_putc(c); disp_move(10, 16); disp_flush(); continue; } break; } return 0; } /* * request_ok() displays the given message and just waits for the user * to press any (printing) key. It is used for diagnostic messages and * similar reports. */ static void request_ok(char *help) { clear_work_area(); disp_setattr(white_on_black); show_txt(8, 11, "Press a key (e.g. ENTER) to continue\n"); show_txt(12, 11, help); disp_move(10, 16); disp_flush(); (void)getch(); /* All characters behave the same here */ } /* * This is an interface to code found in the #included file "car.c" * that contains the Codemist file compression code and archive * utility. It sets up various workspace and invokes file decompression. */ static void decompress_files() { int32 i; for (i=0; i 0 ? toupper(argv[0][0]) : 'A'); break; default: signal(SIGTERM, SIG_IGN); rc = EXIT_FAILURE; break; } /* * Re-instate the screen-mode that was active when I started */ disp_close(); if (vm != 3) disp_setmode(vm); /* * Restore previous screen contents and cursor position */ disp_open(); disp_pokebox(ssave, 0, 0, nrows-1, ncols-1); disp_move(crow, ccol); disp_flush(); disp_close(); exit(rc); return 0; } /* end of install.c */