Annotation of sys/arch/hp300/stand/mkboot/mkboot.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: mkboot.c,v 1.5 2006/08/17 06:31:10 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1990, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. Neither the name of the University nor the names of its contributors
! 16: * may be used to endorse or promote products derived from this software
! 17: * without specific prior written permission.
! 18: *
! 19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 29: * SUCH DAMAGE.
! 30: *
! 31: * @(#)mkboot.c 8.1 (Berkeley) 7/15/93
! 32: */
! 33:
! 34: #ifndef lint
! 35: static char copyright[] =
! 36: "@(#) Copyright (c) 1990, 1993\n\
! 37: The Regents of the University of California. All rights reserved.\n";
! 38: #endif /* not lint */
! 39:
! 40: #ifndef lint
! 41: #if 0
! 42: static char sccsid[] = "@(#)mkboot.c 7.2 (Berkeley) 12/16/90";
! 43: static char rcsid[] = "$NetBSD: mkboot.c,v 1.5 1994/10/26 07:27:45 cgd Exp $";
! 44: #endif
! 45: static char rcsid[] = "$OpenBSD: mkboot.c,v 1.5 2006/08/17 06:31:10 miod Exp $";
! 46: #endif /* not lint */
! 47:
! 48: #include <unistd.h>
! 49: #include <string.h>
! 50: #include <sys/param.h>
! 51: #include <sys/file.h>
! 52: #include <a.out.h>
! 53:
! 54: #include "volhdr.h"
! 55:
! 56: #include <stdio.h>
! 57: #include <ctype.h>
! 58:
! 59: #define LIF_NUMDIR 8
! 60:
! 61: #define LIF_VOLSTART 0
! 62: #define LIF_VOLSIZE sizeof(struct lifvol)
! 63: #define LIF_DIRSTART 512
! 64: #define LIF_DIRSIZE (LIF_NUMDIR * sizeof(struct lifdir))
! 65: #define LIF_FILESTART 8192
! 66:
! 67: #define btolifs(b) (((b) + (SECTSIZE - 1)) / SECTSIZE)
! 68: #define lifstob(s) ((s) * SECTSIZE)
! 69:
! 70: int lpflag;
! 71: int loadpoint;
! 72: struct load ld;
! 73: struct lifvol lifv;
! 74: struct lifdir lifd[LIF_NUMDIR];
! 75: struct exec ex;
! 76: char buf[10240];
! 77:
! 78: void bcddate(int, char *);
! 79: char * lifname(char *);
! 80: void putfile(int, int);
! 81: void usage(void);
! 82:
! 83: /*
! 84: * Old Format:
! 85: * sector 0: LIF volume header (40 bytes)
! 86: * sector 1: <unused>
! 87: * sector 2: LIF directory (8 x 32 == 256 bytes)
! 88: * sector 3-: LIF file 0, LIF file 1, etc.
! 89: * where sectors are 256 bytes.
! 90: *
! 91: * New Format:
! 92: * sector 0: LIF volume header (40 bytes)
! 93: * sector 1: <unused>
! 94: * sector 2: LIF directory (8 x 32 == 256 bytes)
! 95: * sector 3: <unused>
! 96: * sector 4-31: disklabel (~300 bytes right now)
! 97: * sector 32-: LIF file 0, LIF file 1, etc.
! 98: */
! 99: int
! 100: main(argc, argv)
! 101: int argc;
! 102: char **argv;
! 103: {
! 104: int ac;
! 105: char **av;
! 106: int from1, from2, from3, to;
! 107: int n;
! 108: char *n1, *n2, *n3;
! 109:
! 110: ac = --argc;
! 111: av = ++argv;
! 112: if (ac == 0)
! 113: usage();
! 114: if (!strcmp(av[0], "-l")) {
! 115: av++;
! 116: ac--;
! 117: if (ac == 0)
! 118: usage();
! 119: sscanf(av[0], "0x%x", &loadpoint);
! 120: lpflag++;
! 121: av++;
! 122: ac--;
! 123: }
! 124: if (ac == 0)
! 125: usage();
! 126: from1 = open(av[0], O_RDONLY, 0);
! 127: if (from1 < 0) {
! 128: perror("open");
! 129: exit(1);
! 130: }
! 131: n1 = av[0];
! 132: av++;
! 133: ac--;
! 134: if (ac == 0)
! 135: usage();
! 136: if (ac > 1) {
! 137: from2 = open(av[0], O_RDONLY, 0);
! 138: if (from2 < 0) {
! 139: perror("open");
! 140: exit(1);
! 141: }
! 142: n2 = av[0];
! 143: av++;
! 144: ac--;
! 145: if (ac > 1) {
! 146: from3 = open(av[0], O_RDONLY, 0);
! 147: if (from3 < 0) {
! 148: perror("open");
! 149: exit(1);
! 150: }
! 151: n3 = av[0];
! 152: av++;
! 153: ac--;
! 154: } else
! 155: from3 = -1;
! 156: } else
! 157: from2 = from3 = -1;
! 158: to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644);
! 159: if (to < 0) {
! 160: perror("open");
! 161: exit(1);
! 162: }
! 163: /* clear possibly unused directory entries */
! 164: bcopy(" ", lifd[1].dir_name, 10);
! 165: lifd[1].dir_type = -1;
! 166: lifd[1].dir_addr = 0;
! 167: lifd[1].dir_length = 0;
! 168: lifd[1].dir_flag = 0xFF;
! 169: lifd[1].dir_exec = 0;
! 170: lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];
! 171: /* record volume info */
! 172: lifv.vol_id = VOL_ID;
! 173: bcopy("BOOT44", lifv.vol_label, 6);
! 174: lifv.vol_addr = btolifs(LIF_DIRSTART);
! 175: lifv.vol_oct = VOL_OCT;
! 176: lifv.vol_dirsize = btolifs(LIF_DIRSIZE);
! 177: lifv.vol_version = 1;
! 178: /* output bootfile one */
! 179: lseek(to, LIF_FILESTART, 0);
! 180: putfile(from1, to);
! 181: n = btolifs(ld.count + sizeof(ld));
! 182: bcopy(lifname(n1), lifd[0].dir_name, 10);
! 183: lifd[0].dir_type = DIR_TYPE;
! 184: lifd[0].dir_addr = btolifs(LIF_FILESTART);
! 185: lifd[0].dir_length = n;
! 186: bcddate(from1, lifd[0].dir_toc);
! 187: lifd[0].dir_flag = DIR_FLAG;
! 188: lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
! 189: lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length;
! 190: /* if there is an optional second boot program, output it */
! 191: if (from2 >= 0) {
! 192: lseek(to, LIF_FILESTART+lifstob(n), 0);
! 193: putfile(from2, to);
! 194: n = btolifs(ld.count + sizeof(ld));
! 195: bcopy(lifname(n2), lifd[1].dir_name, 10);
! 196: lifd[1].dir_type = DIR_TYPE;
! 197: lifd[1].dir_addr = lifv.vol_length;
! 198: lifd[1].dir_length = n;
! 199: bcddate(from2, lifd[1].dir_toc);
! 200: lifd[1].dir_flag = DIR_FLAG;
! 201: lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
! 202: lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length;
! 203: }
! 204: /* ditto for three */
! 205: if (from3 >= 0) {
! 206: lseek(to, LIF_FILESTART+lifstob(lifd[0].dir_length+n), 0);
! 207: putfile(from3, to);
! 208: n = btolifs(ld.count + sizeof(ld));
! 209: bcopy(lifname(n3), lifd[2].dir_name, 10);
! 210: lifd[2].dir_type = DIR_TYPE;
! 211: lifd[2].dir_addr = lifv.vol_length;
! 212: lifd[2].dir_length = n;
! 213: bcddate(from3, lifd[2].dir_toc);
! 214: lifd[2].dir_flag = DIR_FLAG;
! 215: lifd[2].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
! 216: lifv.vol_length = lifd[2].dir_addr + lifd[2].dir_length;
! 217: }
! 218: /* output volume/directory header info */
! 219: lseek(to, LIF_VOLSTART, 0);
! 220: write(to, &lifv, LIF_VOLSIZE);
! 221: lseek(to, LIF_DIRSTART, 0);
! 222: write(to, lifd, LIF_DIRSIZE);
! 223: return (0);
! 224: }
! 225:
! 226: void
! 227: putfile(int from, int to)
! 228: {
! 229: int n, tcnt, dcnt;
! 230:
! 231: n = read(from, &ex, sizeof(ex));
! 232: if (n != sizeof(ex)) {
! 233: fprintf(stderr, "error reading file header\n");
! 234: exit(1);
! 235: }
! 236: if (N_GETMAGIC(ex) == OMAGIC) {
! 237: tcnt = ex.a_text;
! 238: dcnt = ex.a_data;
! 239: }
! 240: else if (N_GETMAGIC(ex) == NMAGIC) {
! 241: tcnt = (ex.a_text + PGOFSET) & ~PGOFSET;
! 242: dcnt = ex.a_data;
! 243: }
! 244: else {
! 245: fprintf(stderr, "bad magic number\n");
! 246: exit(1);
! 247: }
! 248: ld.address = lpflag ? loadpoint : ex.a_entry;
! 249: ld.count = tcnt + dcnt;
! 250: write(to, &ld, sizeof(ld));
! 251: while (tcnt) {
! 252: n = sizeof(buf);
! 253: if (n > tcnt)
! 254: n = tcnt;
! 255: n = read(from, buf, n);
! 256: if (n < 0) {
! 257: perror("read");
! 258: exit(1);
! 259: }
! 260: if (n == 0) {
! 261: fprintf(stderr, "short read\n");
! 262: exit(1);
! 263: }
! 264: if (write(to, buf, n) < 0) {
! 265: perror("write");
! 266: exit(1);
! 267: }
! 268: tcnt -= n;
! 269: }
! 270: while (dcnt) {
! 271: n = sizeof(buf);
! 272: if (n > dcnt)
! 273: n = dcnt;
! 274: n = read(from, buf, n);
! 275: if (n < 0) {
! 276: perror("read");
! 277: exit(1);
! 278: }
! 279: if (n == 0) {
! 280: fprintf(stderr, "short read\n");
! 281: exit(1);
! 282: }
! 283: if (write(to, buf, n) < 0) {
! 284: perror("write");
! 285: exit(1);
! 286: }
! 287: dcnt -= n;
! 288: }
! 289: }
! 290:
! 291: void
! 292: usage()
! 293: {
! 294: fprintf(stderr,
! 295: "usage: mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n");
! 296: exit(1);
! 297: }
! 298:
! 299: char *
! 300: lifname(str)
! 301: char *str;
! 302: {
! 303: static char lname[10] = "SYS_XXXXX";
! 304: int i;
! 305:
! 306: for (i = 4; i < 10; i++) {
! 307: if (islower(*str))
! 308: lname[i] = toupper(*str);
! 309: else if (isalnum(*str) || *str == '_')
! 310: lname[i] = *str;
! 311: else
! 312: break;
! 313: str++;
! 314: }
! 315: for ( ; i < 10; i++)
! 316: lname[i] = ' ';
! 317: return(lname);
! 318: }
! 319:
! 320: #include <sys/stat.h>
! 321: #include <time.h> /* XXX */
! 322:
! 323: void
! 324: bcddate(fd, toc)
! 325: int fd;
! 326: char *toc;
! 327: {
! 328: struct stat statb;
! 329: struct tm *tm;
! 330:
! 331: fstat(fd, &statb);
! 332: tm = localtime(&statb.st_ctime);
! 333: *toc = ((tm->tm_mon+1) / 10) << 4;
! 334: *toc++ |= (tm->tm_mon+1) % 10;
! 335: *toc = (tm->tm_mday / 10) << 4;
! 336: *toc++ |= tm->tm_mday % 10;
! 337: *toc = (tm->tm_year / 10) << 4;
! 338: *toc++ |= tm->tm_year % 10;
! 339: *toc = (tm->tm_hour / 10) << 4;
! 340: *toc++ |= tm->tm_hour % 10;
! 341: *toc = (tm->tm_min / 10) << 4;
! 342: *toc++ |= tm->tm_min % 10;
! 343: *toc = (tm->tm_sec / 10) << 4;
! 344: *toc |= tm->tm_sec % 10;
! 345: }
CVSweb