Subversion Repositories SvarDOS

Rev

Rev 1661 | Rev 1664 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
28 mv_fox 1
/*
190 mateuszvis 2
 * SVARDOS INSTALL PROGRAM
206 mateuszvis 3
 *
190 mateuszvis 4
 * PUBLISHED UNDER THE TERMS OF THE MIT LICENSE
42 mv_fox 5
 *
1624 mateusz.vi 6
 * COPYRIGHT (C) 2016-2024 MATEUSZ VISTE, ALL RIGHTS RESERVED.
94 mv_fox 7
 *
190 mateuszvis 8
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * copy of this software and associated documentation files (the "Software"),
10
 * to deal in the Software without restriction, including without limitation
11
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 * and/or sell copies of the Software, and to permit persons to whom the
13
 * Software is furnished to do so, subject to the following conditions:
94 mv_fox 14
 *
190 mateuszvis 15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
94 mv_fox 17
 *
190 mateuszvis 18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
 * DEALINGS IN THE SOFTWARE.
94 mv_fox 25
 *
868 mateusz.vi 26
 * http://svardos.org
28 mv_fox 27
 */
28
 
29
#include <dos.h>
30 mv_fox 30
#include <direct.h>  /* mkdir() */
28 mv_fox 31
#include <stdio.h>   /* printf() and friends */
32
#include <stdlib.h>  /* system() */
33
#include <string.h>  /* memcpy() */
34
#include <unistd.h>
42 mv_fox 35
 
1662 mateusz.vi 36
#include "mdr\cout.h"
1661 mateusz.vi 37
#include "mdr\dos.h"
624 mateuszvis 38
#include "svarlang.lib\svarlang.h"
42 mv_fox 39
 
67 mv_fox 40
/* keyboard layouts and locales */
41
#include "keylay.h"
42
#include "keyoff.h"
42 mv_fox 43
 
908 mateusz.vi 44
/* prototype of the int24hdl() function defined in int24hdl.asm */
45
void int24hdl(void);
46
 
47
 
29 mv_fox 48
/* color scheme (color, mono) */
1662 mateusz.vi 49
static unsigned char COLOR_TITLEBAR[2] = {0x70,0x70};
50
static unsigned char COLOR_BODY[2] = {0x07,0x17};
51
static unsigned char COLOR_SELECT[2] = {0x70,0x70};
52
static unsigned char COLOR_SELECTCUR[2] = {0x07,0x1F};
28 mv_fox 53
 
1662 mateusz.vi 54
/* mono flag (0=mono 1=color) */
55
static unsigned char mono = 0;
28 mv_fox 56
 
190 mateuszvis 57
/* how much disk space does SvarDOS require (in MiB) */
58
#define SVARDOS_DISK_REQ 8
28 mv_fox 59
 
73 mv_fox 60
/* menu screens can output only one of these: */
61
#define MENUNEXT 0
62
#define MENUPREV -1
63
#define MENUQUIT -2
64
 
67 mv_fox 65
/* a convenience 'function' used for debugging */
66
#define DBG(x) { video_putstringfix(24, 0, 0x4F00u, x, 80); }
47 mv_fox 67
 
67 mv_fox 68
struct slocales {
69
  char lang[4];
624 mateuszvis 70
  const char *keybcode;
67 mv_fox 71
  unsigned int codepage;
72
  int egafile;
73
  int keybfile;
74
  int keyboff;
75
  int keyblen;
96 mv_fox 76
  unsigned int keybid;
67 mv_fox 77
};
78
 
79
 
1662 mateusz.vi 80
/* put a string on screen and fill it until w chars with whilte space */
81
static void video_putstringfix(unsigned char y, unsigned char x, unsigned char attr, const char *s, unsigned char w) {
82
  unsigned char i;
83
 
84
  /* print the string up to w characters */
85
  i = mdr_cout_str(y, x, s, attr, w);
86
 
87
  /* fill in left space (if any) with blanks */
88
  mdr_cout_char_rep(y, x + i, ' ', attr, w - i);
89
}
90
 
91
 
28 mv_fox 92
/* reboot the computer */
93
static void reboot(void) {
94
  void ((far *bootroutine)()) = (void (far *)()) 0xFFFF0000L;
95
  int far *rstaddr = (int far *)0x00400072L; /* BIOS boot flag is at 0040:0072 */
96
  *rstaddr = 0x1234; /* 0x1234 = warm boot, 0 = cold boot */
97
  (*bootroutine)(); /* jump to the BIOS reboot routine at FFFF:0000 */
98
}
99
 
42 mv_fox 100
 
56 mv_fox 101
/* outputs a string to screen with taking care of word wrapping. returns amount of lines. */
1662 mateusz.vi 102
static unsigned char putstringwrap(unsigned char y, unsigned char x, unsigned char attr, const char *s) {
103
  unsigned char linew, lincount;
104
  linew = 80 - (x << 1);
56 mv_fox 105
 
106
  for (lincount = 1; y+lincount < 25; lincount++) {
107
    int i, len = linew;
108
    for (i = 0; i <= linew; i++) {
109
      if (s[i] == ' ') len = i;
110
      if (s[i] == '\n') {
111
        len = i;
112
        break;
113
      }
114
      if (s[i] == 0) {
115
        len = i;
116
        break;
117
      }
118
    }
1662 mateusz.vi 119
    mdr_cout_str(y++, x, s, attr, len);
56 mv_fox 120
    s += len;
121
    if (*s == 0) break;
122
    s += 1; /* skip the whitespace char */
123
  }
124
  return(lincount);
125
}
126
 
127
 
128
/* an NLS wrapper around video_putstring(), also performs line wrapping when
129
 * needed. returns the amount of lines that were output */
1662 mateusz.vi 130
static unsigned char putstringnls(unsigned char y, unsigned char x, unsigned char attr, unsigned char nlsmaj, unsigned char nlsmin) {
624 mateuszvis 131
  const char *s = svarlang_str(nlsmaj, nlsmin);
132
  if (s == NULL) s = "";
56 mv_fox 133
  return(putstringwrap(y, x, attr, s));
42 mv_fox 134
}
135
 
136
 
280 mateuszvis 137
/* copy file f1 to f2 using buff as a buffer of buffsz bytes. f2 will be overwritten if it
138
 * exists already! returns 0 on success. */
139
static int fcopy(const char *f2, const char *f1, void *buff, size_t buffsz) {
140
  FILE *fd1, *fd2;
141
  size_t sz;
142
  int res = -1; /* assume failure */
143
 
144
  /* open files */
145
  fd1 = fopen(f1, "rb");
146
  fd2 = fopen(f2, "wb");
147
  if ((fd1 == NULL) || (fd2 == NULL)) goto QUIT;
148
 
149
  /* copy data */
150
  for (;;) {
151
    sz = fread(buff, 1, buffsz, fd1);
152
    if (sz == 0) {
153
      if (feof(fd1) != 0) break;
154
      goto QUIT;
155
    }
156
    if (fwrite(buff, 1, sz, fd2) != sz) goto QUIT;
157
  }
158
 
159
  res = 0; /* success */
160
 
161
  QUIT:
162
  if (fd1 != NULL) fclose(fd1);
163
  if (fd2 != NULL) fclose(fd2);
164
  return(res);
165
}
166
 
167
 
1662 mateusz.vi 168
static int menuselect(unsigned char ypos, int xpos, unsigned char height, const char **list, int listlen) {
28 mv_fox 169
  int i, offset = 0, res = 0, count, width = 0;
1662 mateusz.vi 170
  unsigned char y;
171
 
67 mv_fox 172
  /* count how many positions there is, and check their width */
173
  for (count = 0; (list[count] != NULL) && (count != listlen); count++) {
28 mv_fox 174
    int len = strlen(list[count]);
175
    if (len > width) width = len;
176
  }
177
 
178
  /* if xpos negative, means 'center out' */
179
  if (xpos < 0) xpos = 39 - (width >> 1);
180
 
1662 mateusz.vi 181
  mdr_cout_char(ypos, xpos+width+2, 0xBF, COLOR_SELECT[mono]);         /*       \ */
182
  mdr_cout_char(ypos, xpos-1, 0xDA, COLOR_SELECT[mono]);               /*  /      */
183
  mdr_cout_char(ypos+height-1, xpos-1, 0xC0, COLOR_SELECT[mono]);      /*  \      */
184
  mdr_cout_char(ypos+height-1, xpos+width+2, 0xD9, COLOR_SELECT[mono]);/*      /  */
185
  mdr_cout_char_rep(ypos, xpos, 0xC4, COLOR_SELECT[mono], width + 2);
186
  mdr_cout_char_rep(ypos+height-1, xpos, 0xC4, COLOR_SELECT[mono], width + 2);
28 mv_fox 187
 
1662 mateusz.vi 188
  for (y = ypos + 1; y < (ypos + height - 1); y++) {
189
    mdr_cout_char(y, xpos-1, 0xB3, COLOR_SELECT[mono]);
190
    mdr_cout_char(y, xpos+width+2, 0xB3, COLOR_SELECT[mono]);
191
  }
192
 
28 mv_fox 193
  for (;;) {
194
    int key;
195
    /* list of selectable items */
196
    for (i = 0; i < height - 2; i++) {
197
      if (i + offset == res) {
1662 mateusz.vi 198
        mdr_cout_char(ypos + 1 + i, xpos, 16, COLOR_SELECTCUR[mono]);
199
        mdr_cout_char(ypos + 1 + i, xpos+width+1, 17, COLOR_SELECTCUR[mono]);
200
        mdr_cout_locate(ypos + 1 + i, xpos);
29 mv_fox 201
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECTCUR[mono], list[i + offset], width);
28 mv_fox 202
      } else if (i + offset < count) {
1662 mateusz.vi 203
        mdr_cout_char(ypos + 1 + i, xpos, ' ', COLOR_SELECT[mono]);
204
        mdr_cout_char(ypos + 1 + i, xpos+width+1, ' ', COLOR_SELECT[mono]);
29 mv_fox 205
        video_putstringfix(ypos + 1 + i, xpos+1, COLOR_SELECT[mono], list[i + offset], width);
28 mv_fox 206
      } else {
1662 mateusz.vi 207
        mdr_cout_char_rep(ypos + 1 + i, xpos, ' ', COLOR_SELECT[mono], width+2);
28 mv_fox 208
      }
209
    }
1661 mateusz.vi 210
    key = mdr_dos_getkey();
28 mv_fox 211
    if (key == 0x0D) { /* ENTER */
212
      return(res);
213
    } else if (key == 0x148) { /* up */
33 mv_fox 214
      if (res > 0) {
215
        res--;
216
        if (res < offset) offset = res;
217
      }
28 mv_fox 218
    } else if (key == 0x150) { /* down */
33 mv_fox 219
      if (res+1 < count) {
220
        res++;
221
        if (res > offset + height - 3) offset = res - (height - 3);
222
      }
223
    } else if (key == 0x147) { /* home */
224
      res = 0;
225
      offset = 0;
226
    } else if (key == 0x14F) { /* end */
227
      res = count - 1;
228
      if (res > offset + height - 3) offset = res - (height - 3);
28 mv_fox 229
    } else if (key == 0x1B) {  /* ESC */
230
      return(-1);
78 mv_fox 231
    }/* else {
33 mv_fox 232
      char buf[8];
55 mv_fox 233
      snprintf(buf, sizeof(buf), "0x%02X ", key);
56 mv_fox 234
      video_putstring(1, 0, COLOR_BODY[mono], buf, -1);
78 mv_fox 235
    }*/
28 mv_fox 236
  }
237
}
238
 
1662 mateusz.vi 239
static void newscreen(unsigned char statusbartype) {
624 mateuszvis 240
  const char *msg;
1662 mateusz.vi 241
  mdr_cout_cls(COLOR_BODY[mono]);
624 mateuszvis 242
  msg = svarlang_strid(0x00); /* "SVARDOS INSTALLATION" */
1662 mateusz.vi 243
  mdr_cout_char_rep(0, 0, ' ', COLOR_TITLEBAR[mono], 80);
244
  mdr_cout_str(0, 40 - (strlen(msg) >> 1), msg, COLOR_TITLEBAR[mono], 80);
79 mv_fox 245
  switch (statusbartype) {
246
    case 1:
624 mateuszvis 247
      msg = svarlang_strid(0x000B); /* "Up/Down = Select entry | Enter = Validate your choice | ESC = Quit to DOS" */
79 mv_fox 248
      break;
249
    case 2:
624 mateuszvis 250
      msg = svarlang_strid(0x0005); /* "Press any key..." */
79 mv_fox 251
      break;
252
    case 3:
253
      msg = "";
254
      break;
255
    default:
624 mateuszvis 256
      msg = svarlang_strid(0x000A); /* "Up/Down = Select entry | Enter = Validate your choice | ESC = Previous screen" */
79 mv_fox 257
      break;
258
  }
1662 mateusz.vi 259
  mdr_cout_char(24, 0, ' ', COLOR_TITLEBAR[mono]);
79 mv_fox 260
  video_putstringfix(24, 1, COLOR_TITLEBAR[mono], msg, 79);
1662 mateusz.vi 261
  mdr_cout_locate(25,0);
28 mv_fox 262
}
263
 
96 mv_fox 264
/* fills a slocales struct accordingly to the value of its keyboff member */
265
static void kblay2slocal(struct slocales *locales) {
624 mateuszvis 266
  const char *m;
96 mv_fox 267
  for (m = kblayouts[locales->keyboff]; *m != 0; m++); /* skip layout name */
268
  m++;
269
  /* skip keyb code and copy it to locales.keybcode */
270
  locales->keybcode = m;
271
  for (; *m != 0; m++);
272
  /* */
273
  locales->codepage = ((unsigned short)m[1] << 8) | m[2];
274
  locales->egafile = m[3];
275
  locales->keybfile = m[4];
276
  locales->keybid = ((unsigned short)m[5] << 8) | m[6];
277
}
278
 
67 mv_fox 279
static int selectlang(struct slocales *locales) {
280
  int choice, x;
624 mateuszvis 281
  const char *msg;
282
  const char *langlist[] = {
67 mv_fox 283
    "English",
1177 mateusz.vi 284
    "Brazilian",
67 mv_fox 285
    "French",
133 mv_fox 286
    "German",
119 mv_fox 287
    "Italian",
67 mv_fox 288
    "Polish",
116 mv_fox 289
    "Russian",
123 mv_fox 290
    "Slovene",
128 mv_fox 291
    "Swedish",
67 mv_fox 292
    "Turkish",
28 mv_fox 293
    NULL
294
  };
295
 
79 mv_fox 296
  newscreen(1);
624 mateuszvis 297
  msg = svarlang_strid(0x0100); /* "Welcome to SvarDOS" */
42 mv_fox 298
  x = 40 - (strlen(msg) >> 1);
1662 mateusz.vi 299
  mdr_cout_str(4, x, msg, COLOR_BODY[mono], 80);
300
  mdr_cout_char_rep(5, x, '=', COLOR_BODY[mono], strlen(msg));
301
 
302
  /* center out the string "Please select your language..." */
303
  msg = svarlang_str(1, 1); /* "Please select your language from the list below:" */
304
  if (strlen(msg) > 74) {
305
    putstringwrap(8, 1, COLOR_BODY[mono], msg);
306
  } else {
307
    mdr_cout_str(8, 40 - (strlen(msg) / 2), msg, COLOR_BODY[mono], 80);
308
  }
309
 
133 mv_fox 310
  choice = menuselect(11, -1, 11, langlist, -1);
73 mv_fox 311
  if (choice < 0) return(MENUPREV);
67 mv_fox 312
  /* populate locales with default values */
313
  memset(locales, 0, sizeof(struct slocales));
314
  switch (choice) {
315
    case 1:
1179 mateusz.vi 316
      strcpy(locales->lang, "BR");
317
      locales->keyboff = OFFLOC_BR;
318
      locales->keyblen = OFFLEN_BR;
319
      break;
320
    case 2:
67 mv_fox 321
      strcpy(locales->lang, "FR");
322
      locales->keyboff = OFFLOC_FR;
323
      locales->keyblen = OFFLEN_FR;
324
      break;
1177 mateusz.vi 325
    case 3:
133 mv_fox 326
      strcpy(locales->lang, "DE");
327
      locales->keyboff = OFFLOC_DE;
328
      locales->keyblen = OFFLEN_DE;
329
      break;
1177 mateusz.vi 330
    case 4:
119 mv_fox 331
      strcpy(locales->lang, "IT");
332
      locales->keyboff = OFFLOC_IT;
333
      locales->keyblen = OFFLEN_IT;
334
      break;
1177 mateusz.vi 335
    case 5:
67 mv_fox 336
      strcpy(locales->lang, "PL");
337
      locales->keyboff = OFFLOC_PL;
338
      locales->keyblen = OFFLEN_PL;
339
      break;
1177 mateusz.vi 340
    case 6:
116 mv_fox 341
      strcpy(locales->lang, "RU");
342
      locales->keyboff = OFFLOC_RU;
343
      locales->keyblen = OFFLEN_RU;
344
      break;
1177 mateusz.vi 345
    case 7:
123 mv_fox 346
      strcpy(locales->lang, "SI");
347
      locales->keyboff = OFFLOC_SI;
348
      locales->keyblen = OFFLEN_SI;
349
      break;
1177 mateusz.vi 350
    case 8:
128 mv_fox 351
      strcpy(locales->lang, "SV");
352
      locales->keyboff = OFFLOC_SV;
353
      locales->keyblen = OFFLEN_SV;
354
      break;
1177 mateusz.vi 355
    case 9:
67 mv_fox 356
      strcpy(locales->lang, "TR");
357
      locales->keyboff = OFFLOC_TR;
358
      locales->keyblen = OFFLEN_TR;
359
      break;
360
    default:
361
      strcpy(locales->lang, "EN");
362
      locales->keyboff = 0;
363
      locales->keyblen = OFFCOUNT;
364
      break;
365
  }
96 mv_fox 366
  /* populate the slocales struct accordingly to the keyboff member */
367
  kblay2slocal(locales);
67 mv_fox 368
  /* */
73 mv_fox 369
  return(MENUNEXT);
28 mv_fox 370
}
371
 
372
 
67 mv_fox 373
static int selectkeyb(struct slocales *locales) {
96 mv_fox 374
  int menuheight, choice;
375
  if (locales->keyblen == 1) return(MENUNEXT); /* do not ask for keyboard layout if only one is available for given language */
79 mv_fox 376
  newscreen(0);
624 mateuszvis 377
  putstringnls(5, 1, COLOR_BODY[mono], 1, 5); /* "SvarDOS supports different keyboard layouts */
96 mv_fox 378
  menuheight = locales->keyblen + 2;
67 mv_fox 379
  if (menuheight > 13) menuheight = 13;
96 mv_fox 380
  choice = menuselect(10, -1, menuheight, &(kblayouts[locales->keyboff]), locales->keyblen);
381
  if (choice < 0) return(MENUPREV);
382
  /* (re)load the keyboard layout & codepage setup */
383
  locales->keyboff += choice;
384
  kblay2slocal(locales);
73 mv_fox 385
  return(MENUNEXT);
67 mv_fox 386
}
387
 
388
 
28 mv_fox 389
/* returns 0 if installation must proceed, non-zero otherwise */
390
static int welcomescreen(void) {
73 mv_fox 391
  int c;
624 mateuszvis 392
  const char *choice[3];
393
  choice[0] = svarlang_strid(0x0001);
394
  choice[1] = svarlang_strid(0x0002);
395
  choice[2] = NULL;
79 mv_fox 396
  newscreen(0);
624 mateuszvis 397
  putstringnls(4, 1, COLOR_BODY[mono], 2, 0); /* "You are about to install SvarDOS */
73 mv_fox 398
  c = menuselect(13, -1, 4, choice, -1);
399
  if (c < 0) return(MENUPREV);
400
  if (c == 0) return(MENUNEXT);
401
  return(MENUQUIT);
28 mv_fox 402
}
403
 
404
 
33 mv_fox 405
/* returns 1 if drive is removable, 0 if not, -1 on error */
406
static int isdriveremovable(int drv) {
28 mv_fox 407
  union REGS r;
33 mv_fox 408
  r.x.ax = 0x4408;
409
  r.h.bl = drv;
28 mv_fox 410
  int86(0x21, &r, &r);
33 mv_fox 411
  /* CF set on error, AX set to 0 if removable, 1 if fixed */
412
  if (r.x.cflag != 0) return(-1);
413
  if (r.x.ax == 0) return(1);
414
  return(0);
28 mv_fox 415
}
416
 
417
 
35 mv_fox 418
/* returns total disk space of drive drv (in MiB, max 2048), or -1 if drive invalid */
419
static int disksize(int drv) {
28 mv_fox 420
  long res;
421
  union REGS r;
422
  r.h.ah = 0x36; /* DOS 2+ get free disk space */
312 mateuszvis 423
  r.h.dl = drv;  /* A=1, B=2, etc */
28 mv_fox 424
  int86(0x21, &r, &r);
425
  if (r.x.ax == 0xffffu) return(-1); /* AX set to FFFFh if drive invalid */
49 mv_fox 426
  res = r.x.ax;  /* sectors per cluster */
427
  res *= r.x.dx; /* dx contains total clusters, bx contains free clusters */
428
  res *= r.x.cx; /* bytes per sector */
429
  res >>= 20;    /* convert bytes to MiB */
430
  return(res);
35 mv_fox 431
}
432
 
433
 
434
/* returns 0 if disk is empty, non-zero otherwise */
435
static int diskempty(int drv) {
436
  unsigned int rc;
437
  int res;
438
  char buff[8];
439
  struct find_t fileinfo;
55 mv_fox 440
  snprintf(buff, sizeof(buff), "%c:\\*.*", 'A' + drv - 1);
35 mv_fox 441
  rc = _dos_findfirst(buff, _A_NORMAL | _A_SUBDIR | _A_HIDDEN | _A_SYSTEM, &fileinfo);
442
  if (rc == 0) {
443
    res = 1; /* call successfull means disk is not empty */
28 mv_fox 444
  } else {
35 mv_fox 445
    res = 0;
28 mv_fox 446
  }
35 mv_fox 447
  /* _dos_findclose(&fileinfo); */ /* apparently required only on OS/2 */
28 mv_fox 448
  return(res);
449
}
450
 
280 mateuszvis 451
#ifdef DEADCODE
200 mateuszvis 452
/* set new DOS "current drive" to drv ('A', 'B', etc). returns 0 on success */
453
static int set_cur_drive(char drv) {
454
  union REGS r;
455
  if ((drv < 'A') || (drv > 'Z')) return(-1);
456
  r.h.ah = 0x0E; /* DOS 1+ SELECT DEFAULT DRIVE */
457
  r.h.dl = drv - 'A';
458
  int86(0x21, &r, &r);
459
  if (r.h.al < drv - 'A') return(-1);
460
  return(0);
461
}
280 mateuszvis 462
#endif
200 mateuszvis 463
 
310 mateuszvis 464
 
465
/* get the DOS "current drive" (0=A:, 1=B:, etc) */
466
static int get_cur_drive(void) {
467
  union REGS r;
468
  r.h.ah = 0x19; /* DOS 1+ GET CURRENT DEFAULT DRIVE */
469
  int86(0x21, &r, &r);
470
  return(r.h.al);
471
}
472
 
473
 
200 mateuszvis 474
/* returns 0 if file exists, non-zero otherwise */
475
static int fileexists(const char *fname) {
476
  FILE *fd;
477
  fd = fopen(fname, "rb");
478
  if (fd == NULL) return(-1);
479
  fclose(fd);
480
  return(0);
481
}
482
 
483
 
898 mateusz.vi 484
/* tries to write an empty file to drive.
485
 * asks DOS to inhibit the int 24h handler for this job, so erros are
486
 * gracefully reported - unfortunately this does not work under FreeDOS because
487
 * the DOS-C kernel does not implement the required flag.
488
 * returns 0 on success (ie. "disk exists and is writeable"). */
489
static unsigned short test_drive_write(char drive, char *buff) {
490
  unsigned short result = 0;
491
  sprintf(buff, "%c:\\SVWRTEST.123", drive);
492
  _asm {
493
    push ax
494
    push bx
495
    push cx
496
    push dx
497
 
498
    mov ah, 0x6c   /* extended open/create file */
499
    mov bx, 0x2001 /* open for write + inhibit int 24h handler */
500
    xor cx, cx     /* file attributes on the created file */
501
    mov dx, 0x0010 /* create file if does not exist, fail if it exists */
502
    mov si, buff   /* filename to create */
503
    int 0x21
504
    jc FAILURE
505
    /* close the file (handle in AX) */
506
    mov bx, ax
507
    mov ah, 0x3e /* close file */
508
    int 0x21
509
    jc FAILURE
510
    /* delete the file */
511
    mov ah, 0x41 /* delete file pointed out by DS:DX */
512
    mov dx, buff
513
    int 0x21
514
    jnc DONE
515
 
516
    FAILURE:
517
    mov result, ax
518
    DONE:
519
 
520
    pop dx
521
    pop cx
522
    pop bx
523
    pop ax
524
  }
525
  return(result);
526
}
527
 
528
 
310 mateuszvis 529
static int preparedrive(char sourcedrv) {
33 mv_fox 530
  int driveremovable;
310 mateuszvis 531
  int selecteddrive = 3; /* default to 'C:' */
36 mv_fox 532
  int cselecteddrive;
35 mv_fox 533
  int ds;
73 mv_fox 534
  int choice;
56 mv_fox 535
  char buff[1024];
312 mateuszvis 536
  int driveid = 1; /* fdisk runs on first drive (unless USB boot) */
537
  if (selecteddrive == get_cur_drive() + 1) { /* get_cur_drive() returns 0-based values (A=0) while selecteddrive is 1-based (A=1) */
538
    selecteddrive = 4; /* use D: if install is run from C: (typically because it was booted from USB?) */
539
    driveid = 2; /* primary drive is the emulated USB storage */
540
  }
36 mv_fox 541
  cselecteddrive = 'A' + selecteddrive - 1;
28 mv_fox 542
  for (;;) {
33 mv_fox 543
    driveremovable = isdriveremovable(selecteddrive);
544
    if (driveremovable < 0) {
624 mateuszvis 545
      const char *list[4];
79 mv_fox 546
      newscreen(0);
624 mateuszvis 547
      list[0] = svarlang_str(0, 3); /* Create a partition automatically */
548
      list[1] = svarlang_str(0, 4); /* Run the FDISK tool */
549
      list[2] = svarlang_str(0, 2); /* Quit to DOS */
550
      list[3] = NULL;
551
      snprintf(buff, sizeof(buff), svarlang_strid(0x0300), cselecteddrive, SVARDOS_DISK_REQ); /* "ERROR: Drive %c: could not be found. Note, that SvarDOS requires at least %d MiB of available disk space */
555 mateuszvis 552
      switch (menuselect(6 + putstringwrap(4, 1, COLOR_BODY[mono], buff), -1, 5, list, -1)) {
33 mv_fox 553
        case 0:
1239 mateusz.vi 554
          sprintf(buff, "FDISK /PRI:MAX %d", driveid);
312 mateuszvis 555
          system(buff);
33 mv_fox 556
          break;
557
        case 1:
1662 mateusz.vi 558
          mdr_cout_cls(0x07);
559
          mdr_cout_locate(0, 0);
312 mateuszvis 560
          sprintf(buff, "FDISK %d", driveid);
561
          system(buff);
33 mv_fox 562
          break;
73 mv_fox 563
        case 2:
564
          return(MENUQUIT);
56 mv_fox 565
        default:
33 mv_fox 566
          return(-1);
567
      }
113 mv_fox 568
      /* write a temporary MBR which only skips the drive (in case BIOS would
569
       * try to boot off the not-yet-ready C: disk) */
1239 mateusz.vi 570
      sprintf(buff, "FDISK /LOADIPL %d", driveid);
312 mateuszvis 571
      system(buff); /* writes BOOT.MBR into actual MBR */
79 mv_fox 572
      newscreen(2);
624 mateuszvis 573
      putstringnls(10, 10, COLOR_BODY[mono], 3, 1); /* "Your computer will reboot now." */
574
      putstringnls(12, 10, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
1661 mateusz.vi 575
      mdr_dos_getkey();
28 mv_fox 576
      reboot();
73 mv_fox 577
      return(MENUQUIT);
33 mv_fox 578
    } else if (driveremovable > 0) {
79 mv_fox 579
      newscreen(2);
624 mateuszvis 580
      snprintf(buff, sizeof(buff), svarlang_strid(0x0302), cselecteddrive); /* "ERROR: Drive %c: is a removable device */
1662 mateusz.vi 581
      mdr_cout_str(9, 1, buff, COLOR_BODY[mono], 80);
624 mateuszvis 582
      putstringnls(11, 2, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
73 mv_fox 583
      return(MENUQUIT);
28 mv_fox 584
    }
33 mv_fox 585
    /* if not formatted, propose to format it right away (try to create a directory) */
898 mateusz.vi 586
    if (test_drive_write(cselecteddrive, buff) != 0) {
624 mateuszvis 587
      const char *list[3];
79 mv_fox 588
      newscreen(0);
624 mateuszvis 589
      snprintf(buff, sizeof(buff), svarlang_str(3, 3), cselecteddrive); /* "ERROR: Drive %c: seems to be unformated. Do you wish to format it?") */
1662 mateusz.vi 590
      mdr_cout_str(7, 1, buff, COLOR_BODY[mono], 80);
556 mateuszvis 591
 
624 mateuszvis 592
      snprintf(buff, sizeof(buff), svarlang_strid(0x0007), cselecteddrive); /* "Format drive %c:" */
556 mateuszvis 593
      list[0] = buff;
624 mateuszvis 594
      list[1] = svarlang_strid(0x0002); /* "Quit to DOS" */
556 mateuszvis 595
      list[2] = NULL;
596
 
73 mv_fox 597
      choice = menuselect(12, -1, 4, list, -1);
598
      if (choice < 0) return(MENUPREV);
599
      if (choice == 1) return(MENUQUIT);
1662 mateusz.vi 600
      mdr_cout_cls(0x07);
601
      mdr_cout_locate(0, 0);
190 mateuszvis 602
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
36 mv_fox 603
      system(buff);
28 mv_fox 604
      continue;
605
    }
33 mv_fox 606
    /* check total disk space */
35 mv_fox 607
    ds = disksize(selecteddrive);
190 mateuszvis 608
    if (ds < SVARDOS_DISK_REQ) {
56 mv_fox 609
      int y = 9;
79 mv_fox 610
      newscreen(2);
624 mateuszvis 611
      snprintf(buff, sizeof(buff), svarlang_strid(0x0304), cselecteddrive, SVARDOS_DISK_REQ); /* "ERROR: Drive %c: is not big enough! SvarDOS requires a disk of at least %d MiB." */
61 mv_fox 612
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
624 mateuszvis 613
      putstringnls(++y, 1, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
1661 mateusz.vi 614
      mdr_dos_getkey();
73 mv_fox 615
      return(MENUQUIT);
28 mv_fox 616
    }
617
    /* is the disk empty? */
79 mv_fox 618
    newscreen(0);
35 mv_fox 619
    if (diskempty(selecteddrive) != 0) {
624 mateuszvis 620
      const char *list[3];
65 mv_fox 621
      int y = 6;
624 mateuszvis 622
      snprintf(buff, sizeof(buff), svarlang_strid(0x0305), cselecteddrive); /* "ERROR: Drive %c: not empty" */
65 mv_fox 623
      y += putstringwrap(y, 1, COLOR_BODY[mono], buff);
556 mateuszvis 624
 
624 mateuszvis 625
      snprintf(buff, sizeof(buff), svarlang_strid(0x0007), cselecteddrive); /* "Format drive %c:" */
556 mateuszvis 626
      list[0] = buff;
624 mateuszvis 627
      list[1] = svarlang_strid(0x0002); /* "Quit to DOS" */
556 mateuszvis 628
      list[2] = NULL;
629
 
73 mv_fox 630
      choice = menuselect(++y, -1, 4, list, -1);
631
      if (choice < 0) return(MENUPREV);
632
      if (choice == 1) return(MENUQUIT);
1662 mateusz.vi 633
      mdr_cout_cls(0x07);
634
      mdr_cout_locate(0, 0);
190 mateuszvis 635
      snprintf(buff, sizeof(buff), "FORMAT %c: /Q /U /Z:seriously /V:SVARDOS", cselecteddrive);
42 mv_fox 636
      system(buff);
28 mv_fox 637
      continue;
638
    } else {
639
      /* final confirmation */
624 mateuszvis 640
      const char *list[3];
641
      list[0] = svarlang_strid(0x0001); /* Install SvarDOS */
642
      list[1] = svarlang_strid(0x0002); /* Quit to DOS */
643
      list[2] = NULL;
644
      snprintf(buff, sizeof(buff), svarlang_strid(0x0306), cselecteddrive); /* "The installation of SvarDOS to %c: is about to begin." */
1662 mateusz.vi 645
      mdr_cout_str(7, 40 - strlen(buff), buff, COLOR_BODY[mono], 80);
73 mv_fox 646
      choice = menuselect(10, -1, 4, list, -1);
647
      if (choice < 0) return(MENUPREV);
648
      if (choice == 1) return(MENUQUIT);
310 mateuszvis 649
      snprintf(buff, sizeof(buff), "SYS %c: %c: > NUL", sourcedrv, cselecteddrive);
36 mv_fox 650
      system(buff);
312 mateuszvis 651
      sprintf(buff, "FDISK /MBR %d", driveid);
652
      system(buff);
55 mv_fox 653
      snprintf(buff, sizeof(buff), "%c:\\TEMP", cselecteddrive);
36 mv_fox 654
      mkdir(buff);
655
      return(cselecteddrive);
28 mv_fox 656
    }
657
  }
658
}
659
 
660
 
280 mateuszvis 661
/* generates locales-related configurations and writes them to file (this
662
 * is used to compute autoexec.bat content) */
663
static void genlocalesconf(FILE *fd, const struct slocales *locales) {
664
  if (locales == NULL) return;
665
 
666
  fprintf(fd, "SET LANG=%s\r\n", locales->lang);
667
 
668
  if (locales->egafile > 0) {
669
    fprintf(fd, "DISPLAY CON=(EGA,,1)\r\n");
670
    if (locales->egafile == 1) {
671
      fprintf(fd, "MODE CON CP PREPARE=((%u) %%DOSDIR%%\\CPI\\EGA.CPX)\r\n", locales->codepage);
672
    } else {
673
      fprintf(fd, "MODE CON CP PREPARE=((%u) %%DOSDIR%%\\CPI\\EGA%d.CPX)\r\n", locales->codepage, locales->egafile);
674
    }
675
    fprintf(fd, "MODE CON CP SELECT=%u\r\n", locales->codepage);
676
  }
677
 
678
  if (locales->keybfile > 0) {
1659 bttr 679
    fprintf(fd, "KEYB %s,%d,%%DOSDIR%%\\", locales->keybcode, locales->codepage);
280 mateuszvis 680
    if (locales->keybfile == 1) {
681
      fprintf(fd, "KEYBOARD.SYS");
682
    } else {
683
      fprintf(fd, "KEYBRD%d.SYS", locales->keybfile);
684
    }
685
    if (locales->keybid != 0) fprintf(fd, " /ID:%d", locales->keybid);
686
    fprintf(fd, "\r\n");
687
  }
688
}
689
 
690
 
691
static void bootfilesgen(char targetdrv, const struct slocales *locales) {
28 mv_fox 692
  char buff[128];
693
  FILE *fd;
53 mv_fox 694
  /*** CONFIG.SYS ***/
280 mateuszvis 695
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\CONFIG.SYS", targetdrv);
53 mv_fox 696
  fd = fopen(buff, "wb");
697
  if (fd == NULL) return;
1633 mateusz.vi 698
  fprintf(fd, "LASTDRIVE=Z\r\n"
1639 mateusz.vi 699
              "FILES=40\r\n");
700
  fprintf(fd, "DEVICE=C:\\SVARDOS\\HIMEMX.EXE\r\n");
1633 mateusz.vi 701
  fprintf(fd, "DOS=UMB,HIGH\r\n");
1104 mateusz.vi 702
  fprintf(fd, "SHELL=C:\\COMMAND.COM /E:512 /P\r\n");
625 mateuszvis 703
  fprintf(fd, "REM COUNTRY=001,%u,C:\\SVARDOS\\CFG\\COUNTRY.SYS\r\n", locales->codepage);
280 mateuszvis 704
  fprintf(fd, "REM DEVICE=C:\\DRIVERS\\UDVD2\\UDVD2.SYS /D:SVCD0001 /H\r\n");
53 mv_fox 705
  fclose(fd);
28 mv_fox 706
  /*** AUTOEXEC.BAT ***/
280 mateuszvis 707
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\AUTOEXEC.BAT", targetdrv);
28 mv_fox 708
  fd = fopen(buff, "wb");
709
  if (fd == NULL) return;
710
  fprintf(fd, "@ECHO OFF\r\n");
280 mateuszvis 711
  fprintf(fd, "SET TEMP=C:\\TEMP\r\n");
712
  fprintf(fd, "SET DOSDIR=C:\\SVARDOS\r\n");
817 mateusz.vi 713
  fprintf(fd, "SET NLSPATH=%%DOSDIR%%\\NLS;.\r\n");
53 mv_fox 714
  fprintf(fd, "SET DIRCMD=/OGNE/P/4\r\n");
303 mateuszvis 715
  fprintf(fd, "SET WATTCP.CFG=%%DOSDIR%%\\CFG\r\n");
1637 mateusz.vi 716
  fprintf(fd, "PATH %%DOSDIR%%\r\n");
28 mv_fox 717
  fprintf(fd, "PROMPT $P$G\r\n");
56 mv_fox 718
  fprintf(fd, "FDAPM APMDOS\r\n");
28 mv_fox 719
  fprintf(fd, "\r\n");
280 mateuszvis 720
  genlocalesconf(fd, locales);
49 mv_fox 721
  fprintf(fd, "\r\n");
280 mateuszvis 722
  fprintf(fd, "REM Uncomment the line below for CDROM support\r\n");
723
  fprintf(fd, "REM SHSUCDX /d:SVCD0001\r\n");
724
  fprintf(fd, "\r\n");
53 mv_fox 725
  fprintf(fd, "ECHO.\r\n");
624 mateuszvis 726
  fprintf(fd, "ECHO %s\r\n", svarlang_strid(0x0600)); /* "Welcome to SvarDOS!" */
28 mv_fox 727
  fclose(fd);
200 mateuszvis 728
  /*** CREATE DIRECTORY FOR CONFIGURATION FILES ***/
277 mateuszvis 729
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS", targetdrv);
200 mateuszvis 730
  mkdir(buff);
277 mateuszvis 731
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG", targetdrv);
53 mv_fox 732
  mkdir(buff);
277 mateuszvis 733
  /*** PKG.CFG ***/
734
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG\\PKG.CFG", targetdrv);
735
  fd = fopen(buff, "wb");
736
  if (fd == NULL) return;
737
  fprintf(fd, "# pkg config file - specifies locations where packages should be installed\r\n"
738
              "\r\n"
1637 mateusz.vi 739
              "# DOS core binaries\r\n"
740
              "DIR BIN C:\\SVARDOS\r\n"
741
              "\r\n"
277 mateuszvis 742
              "# Programs\r\n"
743
              "DIR PROGS C:\\\r\n"
744
              "\r\n"
745
              "# Games \r\n"
746
              "DIR GAMES C:\\\r\n"
747
              "\r\n"
748
              "# Drivers\r\n"
749
              "DIR DRIVERS C:\\DRIVERS\r\n"
750
              "\r\n"
751
              "# Development tools\r\n"
752
              "DIR DEVEL C:\\DEVEL\r\n");
753
  fclose(fd);
53 mv_fox 754
  /*** COUNTRY.SYS ***/
755
  /*** PICOTCP ***/
756
  /*** WATTCP ***/
303 mateuszvis 757
  snprintf(buff, sizeof(buff), "%c:\\SVARDOS\\CFG\\WATTCP.CFG", targetdrv);
758
  fd = fopen(buff, "wb");
759
  if (fd == NULL) return;
760
  fprintf(fd, "my_ip = dhcp\r\n"
761
              "#my_ip = 192.168.0.7\r\n"
762
              "#netmask = 255.255.255.0\r\n"
763
              "#nameserver = 192.168.0.1\r\n"
764
              "#nameserver = 192.168.0.2\r\n"
554 mateuszvis 765
              "#gateway = 192.168.0.1\r\n");
303 mateuszvis 766
  fclose(fd);
28 mv_fox 767
}
768
 
769
 
868 mateusz.vi 770
static int installpackages(char targetdrv, char srcdrv, const struct slocales *locales, const char *buildstring) {
192 mateuszvis 771
  char pkglist[512];
30 mv_fox 772
  int i, pkglistlen;
192 mateuszvis 773
  size_t pkglistflen;
280 mateuszvis 774
  char buff[1024]; /* must be *at least* 1 sector big for efficient file copying */
775
  FILE *fd = NULL;
192 mateuszvis 776
  char *pkgptr;
79 mv_fox 777
  newscreen(3);
192 mateuszvis 778
  /* load pkg list */
779
  fd = fopen("install.lst", "rb");
780
  if (fd == NULL) {
1662 mateusz.vi 781
    mdr_cout_str(10, 30, "ERROR: INSTALL.LST NOT FOUND", COLOR_BODY[mono], 80);
1661 mateusz.vi 782
    mdr_dos_getkey();
192 mateuszvis 783
    return(-1);
784
  }
1125 mateusz.vi 785
  pkglistflen = fread(pkglist, 1, sizeof(pkglist) - 2, fd);
192 mateuszvis 786
  fclose(fd);
1125 mateusz.vi 787
  if (pkglistflen == sizeof(pkglist) - 2) {
1662 mateusz.vi 788
    mdr_cout_str(10, 30, "ERROR: INSTALL.LST TOO LARGE", COLOR_BODY[mono], 80);
1661 mateusz.vi 789
    mdr_dos_getkey();
192 mateuszvis 790
    return(-1);
791
  }
1125 mateusz.vi 792
  /* mark the end of list */
793
  pkglist[pkglistflen] = 0;
794
  pkglist[pkglistflen + 1] = 0xff;
192 mateuszvis 795
  /* replace all \r and \n chars by 0 bytes, and count the number of packages */
796
  pkglistlen = 0;
797
  for (i = 0; i < pkglistflen; i++) {
798
    switch (pkglist[i]) {
799
      case '\n':
800
        pkglistlen++;
801
        /* FALLTHRU */
802
      case '\r':
803
        pkglist[i] = 0;
804
        break;
805
    }
806
  }
280 mateuszvis 807
  /* copy pkg.exe to the new drive, along with all packages */
808
  snprintf(buff, sizeof(buff), "%c:\\TEMP\\pkg.exe", targetdrv);
809
  snprintf(buff + 64, sizeof(buff) - 64, "%c:\\pkg.exe", srcdrv);
810
  fcopy(buff, buff + 64, buff, sizeof(buff));
811
 
812
  /* open the post-install autoexec.bat and prepare initial instructions */
813
  snprintf(buff, sizeof(buff), "%c:\\temp\\postinst.bat", targetdrv);
814
  fd = fopen(buff, "wb");
815
  if (fd == NULL) return(-1);
868 mateusz.vi 816
  fprintf(fd, "@ECHO OFF\r\nECHO INSTALLING SVARDOS BUILD %s\r\n", buildstring);
280 mateuszvis 817
 
1104 mateusz.vi 818
  /* move COMMAND.COM so it does not clashes with the installation of the SVARCOM package */
819
  fprintf(fd, "COPY \\COMMAND.COM \\CMD.COM\r\n");
820
  fprintf(fd, "SET COMSPEC=%c:\\CMD.COM\r\n", targetdrv);
821
  fprintf(fd, "DEL \\COMMAND.COM\r\n");
822
 
280 mateuszvis 823
  /* copy packages */
192 mateuszvis 824
  for (i = 0;; i++) {
1125 mateusz.vi 825
    RETRY_ENTIRE_LIST:
826
 
192 mateuszvis 827
    /* move forward to nearest entry or end of list */
1125 mateusz.vi 828
    for (pkgptr = pkglist; *pkgptr == 0; pkgptr++);
829
    if (*pkgptr == 0xff) break; /* end of list: means all packages have been processed */
830
 
831
    /* is this package present on the floppy disk? */
832
    TRY_NEXTPKG:
833
    sprintf(buff, "%s.svp", pkgptr);
834
    if (fileexists(buff) != 0) {
835
      while (*pkgptr != 0) pkgptr++;
836
      while (*pkgptr == 0) pkgptr++;
837
      /* end of list? ask for next floppy, there's nothing interesting left on this one */
838
      if (*pkgptr == 0xff) {
839
        putstringnls(12, 1, COLOR_BODY[mono], 4, 1); /* "INSERT THE DISK THAT CONTAINS THE REQUIRED FILE AND PRESS ANY KEY" */
1661 mateusz.vi 840
        mdr_dos_getkey();
1125 mateusz.vi 841
        video_putstringfix(12, 1, COLOR_BODY[mono], "", 80); /* erase the 'insert disk' message */
842
        goto RETRY_ENTIRE_LIST;
843
      }
844
      goto TRY_NEXTPKG;
845
    }
846
 
192 mateuszvis 847
    /* install the package */
624 mateuszvis 848
    snprintf(buff, sizeof(buff), svarlang_strid(0x0400), i+1, pkglistlen, pkgptr); /* "Installing package %d/%d: %s" */
36 mv_fox 849
    strcat(buff, "       ");
1662 mateusz.vi 850
    mdr_cout_str(10, 1, buff, COLOR_BODY[mono], 40);
1125 mateusz.vi 851
 
852
    /* proceed with package copy */
853
    sprintf(buff, "%c:\\temp\\%s.svp", targetdrv, pkgptr);
854
    if (fcopy(buff, buff + 7, buff, sizeof(buff)) != 0) {
1662 mateusz.vi 855
      mdr_cout_str(10, 30, "READ ERROR", COLOR_BODY[mono], 80);
1661 mateusz.vi 856
      mdr_dos_getkey();
280 mateuszvis 857
      fclose(fd);
192 mateuszvis 858
      return(-1);
55 mv_fox 859
    }
280 mateuszvis 860
    /* write install instruction to post-install script */
700 mateusz.vi 861
    fprintf(fd, "pkg install %s.svp\r\ndel %s.svp\r\n", pkgptr, pkgptr);
1125 mateusz.vi 862
    /* jump to next entry or end of list and zero out the pkg name in the process */
863
    while ((*pkgptr != 0) && (*pkgptr != 0xff)) {
864
      *pkgptr = 0;
865
      pkgptr++;
866
    }
28 mv_fox 867
  }
280 mateuszvis 868
  /* set up locales so the "installation over" message is nicely displayed */
869
  genlocalesconf(fd, locales);
870
  /* replace autoexec.bat and config.sys now and write some nice message on screen */
871
  fprintf(fd, "DEL pkg.exe\r\n"
872
              "COPY CONFIG.SYS C:\\\r\n"
873
              "DEL CONFIG.SYS\r\n"
874
              "DEL C:\\AUTOEXEC.BAT\r\n"
875
              "COPY AUTOEXEC.BAT C:\\\r\n"
1104 mateusz.vi 876
              "DEL AUTOEXEC.BAT\r\n"
1109 bttr 877
              "SET COMSPEC=C:\\COMMAND.COM\r\n"
1104 mateusz.vi 878
              "DEL \\CMD.COM\r\n");
280 mateuszvis 879
  /* print out the "installation over" message */
880
  fprintf(fd, "ECHO.\r\n"
868 mateusz.vi 881
              "ECHO ");
882
  fprintf(fd, svarlang_strid(0x0501), buildstring); /* "SvarDOS installation is over. Please restart your computer now" */
883
  fprintf(fd, "\r\n"
884
              "ECHO.\r\n");
280 mateuszvis 885
  fclose(fd);
886
 
887
  /* prepare a dummy autoexec.bat that will call temp\postinst.bat */
888
  snprintf(buff, sizeof(buff), "%c:\\autoexec.bat", targetdrv);
889
  fd = fopen(buff, "wb");
890
  if (fd == NULL) return(-1);
891
  fprintf(fd, "@ECHO OFF\r\n"
892
              "SET DOSDIR=C:\\SVARDOS\r\n"
893
              "SET NLSPATH=%%DOSDIR%%\\NLS\r\n"
1659 bttr 894
              "PATH %%DOSDIR%%\r\n");
280 mateuszvis 895
  fprintf(fd, "CD TEMP\r\n"
896
              "postinst.bat\r\n");
897
  fclose(fd);
898
 
192 mateuszvis 899
  return(0);
28 mv_fox 900
}
901
 
902
 
42 mv_fox 903
static void finalreboot(void) {
56 mv_fox 904
  int y = 9;
79 mv_fox 905
  newscreen(2);
624 mateuszvis 906
  y += putstringnls(y, 1, COLOR_BODY[mono], 5, 0); /* "Your computer will reboot now.\nPlease remove the installation disk from your drive" */
907
  putstringnls(++y, 1, COLOR_BODY[mono], 0, 5); /* "Press any key..." */
1661 mateusz.vi 908
  mdr_dos_getkey();
42 mv_fox 909
  reboot();
910
}
911
 
912
 
192 mateuszvis 913
static void loadcp(const struct slocales *locales) {
42 mv_fox 914
  char buff[64];
67 mv_fox 915
  if (locales->codepage == 437) return;
1662 mateusz.vi 916
  mdr_cout_locate(1, 0);
67 mv_fox 917
  if (locales->egafile == 1) {
310 mateuszvis 918
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) EGA.CPX) > NUL", locales->codepage);
42 mv_fox 919
  } else {
310 mateuszvis 920
    snprintf(buff, sizeof(buff), "MODE CON CP PREP=((%u) EGA%d.CPX) > NUL", locales->codepage, locales->egafile);
42 mv_fox 921
  }
922
  system(buff);
67 mv_fox 923
  snprintf(buff, sizeof(buff), "MODE CON CP SEL=%u > NUL", locales->codepage);
42 mv_fox 924
  system(buff);
925
  /* below I re-init the video controller - apparently this is required if
65 mv_fox 926
   * I want the new glyph symbols to be actually applied, at least some
927
   * (broken?) BIOSes, like VBox, apply glyphs only at next video mode change */
42 mv_fox 928
  {
929
  union REGS r;
930
  r.h.ah = 0x0F; /* get current video mode */
931
  int86(0x10, &r, &r); /* r.h.al contains the current video mode now */
56 mv_fox 932
  r.h.al |= 128; /* set the high bit of AL to instruct BIOS not to flush VRAM's content (EGA+) */
933
  r.h.ah = 0; /* re-set video mode (to whatever is set in AL) */
42 mv_fox 934
  int86(0x10, &r, &r);
935
  }
936
}
937
 
200 mateuszvis 938
 
310 mateuszvis 939
#ifdef DEADCODE
193 mateuszvis 940
/* checks that drive drv contains SvarDOS packages
65 mv_fox 941
 * returns 0 if found, non-zero otherwise */
193 mateuszvis 942
static int checkinstsrc(char drv) {
943
  char fname[16];
700 mateusz.vi 944
  snprintf(fname, sizeof(fname), "%c:\\ATTRIB.SVP", drv);
200 mateuszvis 945
  return(fileexists(fname));
69 mv_fox 946
}
310 mateuszvis 947
#endif
65 mv_fox 948
 
949
 
868 mateusz.vi 950
int main(int argc, char **argv) {
67 mv_fox 951
  struct slocales locales;
28 mv_fox 952
  int targetdrv;
193 mateuszvis 953
  int sourcedrv;
73 mv_fox 954
  int action;
868 mateusz.vi 955
  const char *buildstring = "###";
28 mv_fox 956
 
908 mateusz.vi 957
  /* setup the internal int 24h handler ("always fail") */
958
  int24hdl();
959
 
868 mateusz.vi 960
  if (argc != 1) buildstring = argv[1];
961
 
310 mateuszvis 962
  sourcedrv = get_cur_drive() + 'A';
53 mv_fox 963
 
29 mv_fox 964
  /* init screen and detect mono status */
1662 mateusz.vi 965
  mono = mdr_cout_init(NULL, NULL);
29 mv_fox 966
 
73 mv_fox 967
 SelectLang:
190 mateuszvis 968
  action = selectlang(&locales); /* welcome to svardos, select your language */
73 mv_fox 969
  if (action != MENUNEXT) goto Quit;
970
  loadcp(&locales);
1462 mateusz.vi 971
  svarlang_load("INSTALL.LNG", locales.lang); /* NLS support */
865 mateusz.vi 972
 
973
 SelectKeyb:
73 mv_fox 974
  action = selectkeyb(&locales);  /* what keyb layout should we use? */
975
  if (action == MENUQUIT) goto Quit;
976
  if (action == MENUPREV) goto SelectLang;
977
 
978
 WelcomeScreen:
190 mateuszvis 979
  action = welcomescreen(); /* what svardos is, ask whether to run live dos or install */
73 mv_fox 980
  if (action == MENUQUIT) goto Quit;
865 mateusz.vi 981
  if (action == MENUPREV) {
982
    if (locales.keyblen > 1) goto SelectKeyb; /* if there is a choice of more than 1 layout, ask for it */
983
    goto SelectLang;
984
  }
312 mateuszvis 985
  targetdrv = preparedrive(sourcedrv); /* what drive should we install from? check avail. space */
73 mv_fox 986
  if (targetdrv == MENUQUIT) goto Quit;
987
  if (targetdrv == MENUPREV) goto WelcomeScreen;
280 mateuszvis 988
  bootfilesgen(targetdrv, &locales); /* generate boot files and other configurations */
868 mateusz.vi 989
  if (installpackages(targetdrv, sourcedrv, &locales, buildstring) != 0) goto Quit;    /* install packages */
73 mv_fox 990
  /*localcfg();*/ /* show local params (currency, etc), and propose to change them (based on localcfg) */
991
  /*netcfg();*/ /* basic networking config */
992
  finalreboot(); /* remove the CD and reboot */
993
 
994
 Quit:
1662 mateusz.vi 995
  mdr_cout_locate(0, 0);
996
  mdr_cout_close();
28 mv_fox 997
  return(0);
998
}