141488Smckusick /* 241488Smckusick * Copyright (c) 1990 The Regents of the University of California. 341488Smckusick * All rights reserved. 441488Smckusick * 541488Smckusick * %sccs.include.redist.c% 641488Smckusick * 7*54073Shibler * @(#)mkboot.c 7.3 (Berkeley) 06/18/92 841488Smckusick */ 941488Smckusick 1041488Smckusick #ifndef lint 1141488Smckusick char copyright[] = 1241488Smckusick "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 1341488Smckusick All rights reserved.\n"; 1441488Smckusick #endif /* not lint */ 1541488Smckusick 1641488Smckusick #ifndef lint 1745790Sbostic static char sccsid[] = "@(#)mkboot.c 7.2 (Berkeley) 12/16/90"; 1841488Smckusick #endif /* not lint */ 1941488Smckusick 20*54073Shibler #include "sys/param.h" 21*54073Shibler #include "sys/exec.h" 22*54073Shibler #include "sys/file.h" 2341488Smckusick #include "volhdr.h" 24*54073Shibler 2541488Smckusick #include <stdio.h> 2641488Smckusick #include <ctype.h> 2741488Smckusick 2841488Smckusick int lpflag; 2941488Smckusick int loadpoint; 3041488Smckusick struct load ld; 3141488Smckusick struct lifvol lifv; 3241488Smckusick struct lifdir lifd[8]; 3341488Smckusick struct exec ex; 3441488Smckusick char buf[10240]; 3541488Smckusick 3641488Smckusick main(argc, argv) 3741488Smckusick char **argv; 3841488Smckusick { 3941488Smckusick int ac; 4041488Smckusick char **av; 4141488Smckusick int from1, from2, to; 4241488Smckusick register int n; 4341488Smckusick char *n1, *n2, *lifname(); 4441488Smckusick 4541488Smckusick ac = --argc; 4641488Smckusick av = ++argv; 4741488Smckusick if (ac == 0) 4841488Smckusick usage(); 4941488Smckusick if (!strcmp(av[0], "-l")) { 5041488Smckusick av++; 5141488Smckusick ac--; 5241488Smckusick if (ac == 0) 5341488Smckusick usage(); 5441488Smckusick sscanf(av[0], "0x%x", &loadpoint); 5541488Smckusick lpflag++; 5641488Smckusick av++; 5741488Smckusick ac--; 5841488Smckusick } 5941488Smckusick if (ac == 0) 6041488Smckusick usage(); 6141488Smckusick from1 = open(av[0], O_RDONLY, 0); 6241488Smckusick if (from1 < 0) { 6341488Smckusick perror("open"); 6441488Smckusick exit(1); 6541488Smckusick } 6641488Smckusick n1 = av[0]; 6741488Smckusick av++; 6841488Smckusick ac--; 6941488Smckusick if (ac == 0) 7041488Smckusick usage(); 7141488Smckusick if (ac == 2) { 7241488Smckusick from2 = open(av[0], O_RDONLY, 0); 7341488Smckusick if (from2 < 0) { 7441488Smckusick perror("open"); 7541488Smckusick exit(1); 7641488Smckusick } 7741488Smckusick n2 = av[0]; 7841488Smckusick av++; 7941488Smckusick ac--; 8041488Smckusick } else 8141488Smckusick from2 = -1; 8241488Smckusick to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644); 8341488Smckusick if (to < 0) { 8441488Smckusick perror("open"); 8541488Smckusick exit(1); 8641488Smckusick } 8741488Smckusick /* clear possibly unused directory entries */ 8841488Smckusick strncpy(lifd[1].dir_name, " ", 10); 8941488Smckusick lifd[1].dir_type = -1; 9041488Smckusick lifd[1].dir_addr = 0; 9141488Smckusick lifd[1].dir_length = 0; 9241488Smckusick lifd[1].dir_flag = 0xFF; 9341488Smckusick lifd[1].dir_exec = 0; 9441488Smckusick lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1]; 9541488Smckusick /* record volume info */ 9641488Smckusick lifv.vol_id = VOL_ID; 9741488Smckusick strncpy(lifv.vol_label, "BOOT43", 6); 9841488Smckusick lifv.vol_addr = 2; 9941488Smckusick lifv.vol_oct = VOL_OCT; 10041488Smckusick lifv.vol_dirsize = 1; 10141488Smckusick lifv.vol_version = 1; 10241488Smckusick /* output bootfile one */ 10341488Smckusick lseek(to, 3 * SECTSIZE, 0); 10441488Smckusick putfile(from1, to); 10541488Smckusick n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE; 10641488Smckusick strcpy(lifd[0].dir_name, lifname(n1)); 10741488Smckusick lifd[0].dir_type = DIR_TYPE; 10841488Smckusick lifd[0].dir_addr = 3; 10941488Smckusick lifd[0].dir_length = n; 110*54073Shibler bcddate(from1, lifd[0].dir_toc); 11141488Smckusick lifd[0].dir_flag = DIR_FLAG; 11241488Smckusick lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry; 11341488Smckusick lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length; 11441488Smckusick /* if there is an optional second boot program, output it */ 11541488Smckusick if (from2 >= 0) { 11641488Smckusick lseek(to, (3 + n) * SECTSIZE, 0); 11741488Smckusick putfile(from2, to); 11841488Smckusick n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE; 11941488Smckusick strcpy(lifd[1].dir_name, lifname(n2)); 12041488Smckusick lifd[1].dir_type = DIR_TYPE; 12141488Smckusick lifd[1].dir_addr = 3 + lifd[0].dir_length; 12241488Smckusick lifd[1].dir_length = n; 123*54073Shibler bcddate(from2, lifd[1].dir_toc); 12441488Smckusick lifd[1].dir_flag = DIR_FLAG; 12541488Smckusick lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry; 12641488Smckusick lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length; 12741488Smckusick } 12841488Smckusick /* output volume/directory header info */ 12941488Smckusick lseek(to, 0 * SECTSIZE, 0); 13041488Smckusick write(to, &lifv, sizeof(lifv)); 13141488Smckusick lseek(to, 2 * SECTSIZE, 0); 13241488Smckusick write(to, lifd, sizeof(lifd)); 13341488Smckusick exit(0); 13441488Smckusick } 13541488Smckusick 13641488Smckusick putfile(from, to) 13741488Smckusick { 13841488Smckusick register int n, tcnt, dcnt; 13941488Smckusick 14041488Smckusick n = read(from, &ex, sizeof(ex)); 14141488Smckusick if (n != sizeof(ex)) { 14241488Smckusick fprintf(stderr, "error reading file header\n"); 14341488Smckusick exit(1); 14441488Smckusick } 14541488Smckusick if (ex.a_magic == OMAGIC) { 14641488Smckusick tcnt = ex.a_text; 14741488Smckusick dcnt = ex.a_data; 14841488Smckusick } 14941488Smckusick else if (ex.a_magic == NMAGIC) { 15041488Smckusick tcnt = (ex.a_text + PGOFSET) & ~PGOFSET; 15141488Smckusick dcnt = ex.a_data; 15241488Smckusick } 15341488Smckusick else { 15441488Smckusick fprintf(stderr, "bad magic number\n"); 15541488Smckusick exit(1); 15641488Smckusick } 15741488Smckusick ld.address = lpflag ? loadpoint : ex.a_entry; 15841488Smckusick ld.count = tcnt + dcnt; 15941488Smckusick write(to, &ld, sizeof(ld)); 16041488Smckusick while (tcnt) { 16141488Smckusick n = sizeof(buf); 16241488Smckusick if (n > tcnt) 16341488Smckusick n = tcnt; 16441488Smckusick n = read(from, buf, n); 16541488Smckusick if (n < 0) { 16641488Smckusick perror("read"); 16741488Smckusick exit(1); 16841488Smckusick } 16941488Smckusick if (n == 0) { 17041488Smckusick fprintf(stderr, "short read\n"); 17141488Smckusick exit(1); 17241488Smckusick } 17341488Smckusick if (write(to, buf, n) < 0) { 17441488Smckusick perror("write"); 17541488Smckusick exit(1); 17641488Smckusick } 17741488Smckusick tcnt -= n; 17841488Smckusick } 17941488Smckusick while (dcnt) { 18041488Smckusick n = sizeof(buf); 18141488Smckusick if (n > dcnt) 18241488Smckusick n = dcnt; 18341488Smckusick n = read(from, buf, n); 18441488Smckusick if (n < 0) { 18541488Smckusick perror("read"); 18641488Smckusick exit(1); 18741488Smckusick } 18841488Smckusick if (n == 0) { 18941488Smckusick fprintf(stderr, "short read\n"); 19041488Smckusick exit(1); 19141488Smckusick } 19241488Smckusick if (write(to, buf, n) < 0) { 19341488Smckusick perror("write"); 19441488Smckusick exit(1); 19541488Smckusick } 19641488Smckusick dcnt -= n; 19741488Smckusick } 19841488Smckusick } 19941488Smckusick 20041488Smckusick usage() 20141488Smckusick { 20241488Smckusick fprintf(stderr, 20341488Smckusick "usage: mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n"); 20441488Smckusick exit(1); 20541488Smckusick } 20641488Smckusick 20741488Smckusick char * 20841488Smckusick lifname(str) 20941488Smckusick char *str; 21041488Smckusick { 21141488Smckusick static char lname[10] = "SYS_XXXXX"; 21241488Smckusick register int i; 21341488Smckusick 21441488Smckusick for (i = 4; i < 9; i++) { 21541488Smckusick if (islower(*str)) 21641488Smckusick lname[i] = toupper(*str); 21741488Smckusick else if (isalnum(*str) || *str == '_') 21841488Smckusick lname[i] = *str; 21941488Smckusick else 22041488Smckusick break; 22141488Smckusick str++; 22241488Smckusick } 22341488Smckusick for ( ; i < 10; i++) 22441488Smckusick lname[i] = '\0'; 22541488Smckusick return(lname); 22641488Smckusick } 227*54073Shibler 228*54073Shibler #include "sys/stat.h" 229*54073Shibler #include "/usr/include/time.h" /* XXX */ 230*54073Shibler 231*54073Shibler bcddate(fd, toc) 232*54073Shibler int fd; 233*54073Shibler char *toc; 234*54073Shibler { 235*54073Shibler struct stat statb; 236*54073Shibler struct tm *tm; 237*54073Shibler 238*54073Shibler fstat(fd, &statb); 239*54073Shibler tm = localtime(&statb.st_ctime); 240*54073Shibler *toc = ((tm->tm_mon+1) / 10) << 4; 241*54073Shibler *toc++ |= (tm->tm_mon+1) % 10; 242*54073Shibler *toc = (tm->tm_mday / 10) << 4; 243*54073Shibler *toc++ |= tm->tm_mday % 10; 244*54073Shibler *toc = (tm->tm_year / 10) << 4; 245*54073Shibler *toc++ |= tm->tm_year % 10; 246*54073Shibler *toc = (tm->tm_hour / 10) << 4; 247*54073Shibler *toc++ |= tm->tm_hour % 10; 248*54073Shibler *toc = (tm->tm_min / 10) << 4; 249*54073Shibler *toc++ |= tm->tm_min % 10; 250*54073Shibler *toc = (tm->tm_sec / 10) << 4; 251*54073Shibler *toc |= tm->tm_sec % 10; 252*54073Shibler } 253