int open_bvdev(const char *bvd, const char *path, int flags) { const struct devsw *dp; const char *cp; BVRef bvr; int i; int len; int unit; int partition; if ((i = open(path, flags)) >= 0) { return i; } if (bvd == NULL || (len = strlen(bvd)) < 2) { return -1; } for (dp=devsw; dp->name; dp++) { if (bvd[0] == dp->name[0] && bvd[1] == dp->name[1]) { unit = 0; partition = 0; /* get optional unit and partition */ if (len >= 5 && bvd[2] == '(') { /* min must be present xx(0) */ cp = &bvd[3]; i = 0; while ((cp - path) < len && isdigit(*cp)) { i = i * 10 + *cp++ - '0'; unit = i; } if (*cp++ == ',') { i = 0; while ((cp - path) < len && isdigit(*cp)) { i = i * 10 + *cp++ - '0'; partition = i; } } } // turbo - bt(0,0) hook if ((dp->biosdev + unit) == 0x101) { // zef - use the ramdisk if available and the alias is active. if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) { bvr = gRAMDiskVolume; } else { bvr = gBIOSBootVolume; } } else { bvr = newBootVolumeRef(dp->biosdev + unit, partition); } return open_bvr(bvr, path, flags); } } return -1; }
int open_bvdev(const char *bvd, const char *path, int flags) { const struct devsw *dp; const char *cp; BVRef bvr; int i; int len; int unit; int partition; if ((i = open(path, flags)) >= 0) { return i; } if (bvd == NULL || (len = strlen(bvd)) < 2) { return -1; } for (dp=devsw; dp->name; dp++) { if (bvd[0] == dp->name[0] && bvd[1] == dp->name[1]) { unit = 0; partition = 0; /* get optional unit and partition */ if (len >= 5 && bvd[2] == '(') { /* min must be present xx(0) */ cp = &bvd[3]; i = 0; while ((cp - path) < len && isdigit(*cp)) { i = i * 10 + *cp++ - '0'; unit = i; } if (*cp++ == ',') { i = 0; while ((cp - path) < len && isdigit(*cp)) { i = i * 10 + *cp++ - '0'; partition = i; } } } bvr = newBootVolumeRef(dp->biosdev + unit, partition); return open_bvr(bvr, path, flags); } } return -1; }
/*! Extracts the volume selector from the pathname, returns the selected BVRef, and sets *outPath to the remainder of the path. If the path did not include a volume selector then the current volume is used. When called with a volume selector the current volume is changed to the selected volume unless the volume selector is that of a ramdisk. */ BVRef getBootVolumeRef( const char * path, const char ** outPath ) { const char * cp; BVRef bvr = gRootVolume; int biosdev = gBIOSDev; // Search for left parenthesis in the path specification. for (cp = path; *cp; cp++) { if (*cp == LP || *cp == '/') break; } if (*cp != LP) // no left paren found { // Path is using the implicit current device so if there is // no current device, then we must fail. cp = path; if ( gRootVolume == NULL ) return NULL; } else if ((cp - path) == 2) // found "xx(" { const struct devsw * dp; const char * xp = path; int i; int unit = -1; int part = -1; cp++; // Check the 2 character device name pointed by 'xp'. for (dp = devsw; dp->name; dp++) { if ((xp[0] == dp->name[0]) && (xp[1] == dp->name[1])) break; // found matching entry } if (dp->name == NULL) { error("Unknown device '%c%c'\n", xp[0], xp[1]); return NULL; } // Extract the optional unit number from the specification. // hd(unit) or hd(unit, part). i = 0; while (*cp >= '0' && *cp <= '9') { i = i * 10 + *cp++ - '0'; unit = i; } // Unit is no longer optional and never really was. // If the user failed to specify it then the unit number from the previous kernDev // would have been used which makes little sense anyway. // For example, if the user did fd()/foobar and the current root device was the // second hard disk (i.e. unit 1) then fd() would select the second floppy drive! if(unit == -1) return NULL; // Extract the optional partition number from the specification. if (*cp == ',') part = atoi(++cp); // If part is not specified part will be -1 whereas before it would have been // whatever the last partition was which makes about zero sense if the device // has been switched. // Skip past the right paren. for ( ; *cp && *cp != RP; cp++) /* LOOP */; if (*cp == RP) cp++; biosdev = dp->biosdev + unit; // turbo - bt(0,0) hook if (biosdev == 0x101) { // zef - use the ramdisk if available and the alias is active. if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) bvr = gRAMDiskVolume; else bvr = gBIOSBootVolume; } else { bvr = newBootVolumeRef(biosdev, part); } if(bvr == NULL) return NULL; } else { // Bad device specifier, skip past the right paren. for ( cp++; *cp && *cp != RP; cp++) /* LOOP */; if (*cp == RP) cp++; // If gRootVolume was NULL, then bvr will be NULL as well which // should be caught by the caller. } // Returns the file path following the device spec. // e.g. 'hd(1,b)mach_kernel' is reduced to 'mach_kernel'. *outPath = cp; return bvr; }