int load_disklabel(struct of_dev *ofdev, struct disklabel *label) { char buf[DEV_BSIZE]; size_t read; int error = 0; char *errmsg = NULL; /* First try to find a disklabel without MBR partitions */ DNPRINTF(BOOT_D_OFDEV, "load_disklabel: trying to read disklabel\n"); if (strategy(ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &read) != 0 || read != DEV_BSIZE || (errmsg = getdisklabel(buf, label))) { #ifdef BOOT_DEBUG if (errmsg) DNPRINTF(BOOT_D_OFDEV, "load_disklabel: getdisklabel says %s\n", errmsg); #endif /* Else try MBR partitions */ errmsg = search_label(ofdev, LABELSECTOR, buf, label, 0); if (errmsg) { printf("load_disklabel: search_label says %s\n", errmsg); error = ERDLAB; } } return (error); }
void function_or_array (struct command *cmd) /* decide whether to perform function or array */ { struct command *fu; fu = search_label (cmd->symname, srmSUBR | srmLINK); if (fu) { cmd->type = cCALL; cmd->pointer = cmd->symname; cmd->symname = NULL; if (infolevel >= DEBUG) { sprintf(errorstring, "converting '%s' to '%s'",explanation[cFUNCTION_OR_ARRAY],explanation[cFUNCTION]); error(DEBUG, errorstring); } } else { if (cmd->type == cFUNCTION_OR_ARRAY) { cmd->tag = CALLARRAY; } else { cmd->tag = CALLSTRINGARRAY; } cmd->type = cDOARRAY; cmd->args = -1; if (infolevel >= DEBUG) { sprintf(errorstring, "converting '%s' to '%s'",explanation[cFUNCTION_OR_ARRAY],explanation[cDOARRAY]); error(DEBUG, errorstring); } } }
void create_subr_link (char *label) /* create link to subroutine */ { char global[200]; char *dot; struct command *cmd; if (!inlib) { error(DEBUG, "not in library, will not create link to subroutine"); return; } dot = strchr (label, '.'); strcpy (global, "main"); strcat (global, dot); /* check, if label is duplicate */ if (search_label (global, srmSUBR | srmLINK | srmLABEL)) { sprintf (string, "duplicate subroutine '%s'", strip (global)); error (ERROR, string); return; } cmd = add_command (cLINK_SUBR, NULL, label); /* store label */ cmd->pointer = my_strdup (global); link_label (cmd); }
/* * Find a valid disklabel. */ static int search_label(struct of_dev *devp, u_long off, u_char *buf, struct disklabel *lp, u_long off0) { size_t nread; struct mbr_partition *p; int i; u_long poff; static int recursion; if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &nread) || nread != DEV_BSIZE) return ERDLAB; if (*(u_int16_t *)&buf[MBR_MAGIC_OFFSET] != sa_htole16(MBR_MAGIC)) return ERDLAB; if (recursion++ <= 1) off0 += off; for (p = (struct mbr_partition *)(buf + MBR_PART_OFFSET), i = 4; --i >= 0; p++) { if (p->mbrp_type == MBR_PTYPE_NETBSD #ifdef COMPAT_386BSD_MBRPART || (p->mbrp_type == MBR_PTYPE_386BSD && (printf("WARNING: old BSD partition ID!\n"), 1) /* XXX XXX - libsa printf() is void */ ) #endif ) { poff = get_long(&p->mbrp_start) + off0; if (strategy(devp, F_READ, poff + 1, DEV_BSIZE, buf, &nread) == 0 && nread == DEV_BSIZE) { if (!getdisklabel(buf, lp)) { recursion--; return 0; } } if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &nread) || nread != DEV_BSIZE) { recursion--; return ERDLAB; } } else if (p->mbrp_type == MBR_PTYPE_EXT) { poff = get_long(&p->mbrp_start); if (!search_label(devp, poff, buf, lp, off0)) { recursion--; return 0; } if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &nread) || nread != DEV_BSIZE) { recursion--; return ERDLAB; } } } recursion--; return ERDLAB; }
void create_label (char *label, int type) /* creates command label */ { struct command *cmd; /* check, if label is duplicate */ if (search_label (label, srmSUBR | srmLINK | srmLABEL)) { sprintf (string, "duplicate %s '%s'", (type == cLABEL) ? "label" : "subroutine", strip (label)); error (ERROR, string); return; } cmd = add_command (type, NULL, label); cmd->pointer = my_strdup (label); add_switch_state(cmd); link_label (cmd); }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; int handle, part; size_t read; char *errmsg = NULL; int error = 0; if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; DNPRINTF(BOOT_D_OFDEV, "devopen: you want %s\n", name); strlcpy(fname, name, sizeof fname); cp = filename(fname, &partition); if (cp) { strlcpy(buf, cp, sizeof buf); *cp = 0; } if (!cp || !*buf) strlcpy(buf, DEFAULT_KERNEL, sizeof buf); if (!*fname) strlcpy(fname, bootdev, sizeof fname); strlcpy(opened_name, fname, sizeof opened_name); if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') strlcat(opened_name, "/", sizeof opened_name); strlcat(opened_name, buf, sizeof opened_name); *file = opened_name + strlen(fname) + 1; DNPRINTF(BOOT_D_OFDEV, "devopen: trying %s\n", fname); if ((handle = OF_finddevice(fname)) == -1) return ENOENT; DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname); if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf); DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname); if ((handle = OF_open(fname)) == -1) { DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname); return ENXIO; } DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname); bzero(&ofdev, sizeof ofdev); ofdev.handle = handle; if (!strcmp(buf, "block")) { ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; /* First try to find a disklabel without MBR partitions */ DNPRINTF(BOOT_D_OFDEV, "devopen: trying to read disklabel\n"); if (strategy(&ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &read) != 0 || read != DEV_BSIZE || (errmsg = getdisklabel(buf, &label))) { #ifdef BOOT_DEBUG if (errmsg) DNPRINTF(BOOT_D_OFDEV, "devopen: getdisklabel says %s\n", errmsg); #endif /* Else try MBR partitions */ errmsg = search_label(&ofdev, LABELSECTOR, buf, &label, 0); if (errmsg) { printf("devopen: search_label says %s\n", errmsg); error = ERDLAB; } if (error && error != ERDLAB) goto bad; } if (error == ERDLAB) { if (partition) /* User specified a parititon, but there is none */ goto bad; /* No, label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; DNPRINTF(BOOT_D_OFDEV, "devopen: setting partition %d " "offset %x\n", part, ofdev.partoff); } of->f_dev = devsw; of->f_devdata = &ofdev; #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); #endif #ifdef SPARC_BOOT_HSFS bcopy(&file_system_cd9660, &file_system[nfsys++], sizeof file_system[0]); #endif DNPRINTF(BOOT_D_OFDEV, "devopen: return 0\n"); return 0; } #ifdef NETBOOT if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = devsw; of->f_devdata = &ofdev; bcopy(&file_system_nfs, file_system, sizeof file_system[0]); nfsys = 1; if (error = net_open(&ofdev)) goto bad; return 0; } #endif error = EFTYPE; bad: DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n", error); OF_close(handle); ofdev.handle = -1; return error; }
void jump (struct command *cmd) /* jump to specific Label; used as goto, gosub or function call */ { struct command *label; struct stackentry *ret; int type; char *dot; type = cmd->type; if (type == cGOSUB || type == cQGOSUB || type == cCALL || type == cQCALL) { /* leave return address for return */ ret = push (); ret->pointer = current; if (type == cGOSUB || type == cQGOSUB) { ret->type = stRET_ADDR; } else { ret->type = stRET_ADDR_CALL; reorder_stack_before_call (ret); } } if (type == cQGOSUB || type == cQGOTO || type == cQCALL) { current = (struct command *) cmd->jump; /* use remembered address */ if (type == cQGOTO && cmd->switch_state && cmd->switch_state->pop_on_qgoto) { /* jump out of switch-statment ? */ pop(stANY); } return; } label = search_label (cmd->pointer, srmSUBR | srmLINK | srmLABEL); if (!label && type == cCALL && (dot = strchr (cmd->pointer, '.'))) { strcpy (string, "main"); strcat (string, dot); label = search_label (string, srmLINK); } if (label) { /* found right label */ current = label; /* jump to new location */ /* use the address instead of the name next time */ cmd->jump = label; switch (cmd->type) { case cGOTO: cmd->type = cQGOTO; cmd->switch_state->pop_on_qgoto = check_leave_switch (cmd, label); if (cmd->switch_state->pop_on_qgoto) { pop(stANY); } break; case cGOSUB: cmd->type = cQGOSUB; break; case cCALL: cmd->type = cQCALL; break; } } else { /* label not found */ sprintf (string, "can't find %s '%s'", (type == cCALL) ? "subroutine" : "label", strip ((char *) cmd->pointer)); if (strchr (cmd->pointer, '@')) { strcat (string, " (not in this sub)"); } error (ERROR, string); } }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; int handle, part; size_t nread; int error = 0; if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; strcpy(fname, name); cp = filename(fname, &partition); if (cp) { strcpy(buf, cp); *cp = 0; } if (!cp || !*buf) return ENOENT; if (!*fname) strcpy(fname, bootdev); strcpy(opened_name, fname); if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') strcat(opened_name, "/"); strcat(opened_name, buf); *file = opened_name + strlen(fname) + 1; if ((handle = OF_finddevice(fname)) == -1) return ENOENT; if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; floppyboot = !strcmp(buf, "floppy"); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; #if 0 if (!strcmp(buf, "block")) /* * For block devices, indicate raw partition * (:0 in OpenFirmware) */ strcat(fname, ":0"); #endif if ((handle = OF_open(fname)) == -1) return ENXIO; memset(&ofdev, 0, sizeof ofdev); ofdev.handle = handle; ofdev.dmabuf = NULL; OF_call_method("dma-alloc", handle, 1, 1, MAXPHYS, &ofdev.dmabuf); if (!strcmp(buf, "block")) { ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; /* First try to find a disklabel without MBR partitions */ if (strategy(&ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &nread) != 0 || nread != DEV_BSIZE || getdisklabel(buf, &label)) { /* Else try MBR partitions */ error = search_label(&ofdev, 0, buf, &label, 0); if (error && error != ERDLAB) goto bad; } if (error == ERDLAB) { if (partition) /* * User specified a parititon, * but there is none */ goto bad; /* No, label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; } of->f_dev = of_devsw; of->f_devdata = &ofdev; file_system[0] = file_system_ffsv1; file_system[1] = file_system_ffsv2; file_system[2] = file_system_lfsv1; file_system[3] = file_system_lfsv2; file_system[4] = file_system_ustarfs; file_system[5] = file_system_cd9660; file_system[6] = file_system_hfs; nfsys = 7; return 0; } if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = of_devsw; of->f_devdata = &ofdev; file_system[0] = file_system_nfs; nfsys = 1; if ((error = net_open(&ofdev))) goto bad; return 0; } error = EFTYPE; bad: OF_close(handle); ofdev.handle = -1; return error; }