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