FreeBSD/sys/boot/userboot/userboot/devicename.c
/*
 * Point (dev) at an allocated device specifier matching the string version
 * at the beginning of (devspec).  Return a pointer to the remaining
 * text in (path).
 *
 * In all cases, the beginning of (devspec) is compared to the names
 * of known devices in the device switch, and then any following text
 * is parsed according to the rules applied to the device type.
 *
 * For disk-type devices, the syntax is:
 *
 * disk<unit>[s<slice>][<partition>]:
 * 
 */
Point (dev) at an allocated device specifier matching the string version
at the beginning of (devspec).  Return a pointer to the remaining
text in (path).

In all cases, the beginning of (devspec) is compared to the names
of known devices in the device switch, and then any following text
is parsed according to the rules applied to the device type.

For disk-type devices, the syntax is.


Point ( dev ) at an allocated device specifier matching the string version at the beginning of ( devspec ) . Return a pointer to the remaining text in ( path ) . In all cases the beginning of ( devspec ) is compared to the names of known devices in the device switch and then any following text is parsed according to the rules applied to the device type . For disk - type devices the syntax is .
static int
userboot_parsedev(struct disk_devdesc **dev, const char *devspec, const char **path)
{
    struct disk_devdesc *idev;
    struct devsw	*dv;
    int			i, unit, err;
    const char		*cp;
    const char		*np;
    if (strlen(devspec) < 2)
	return(EINVAL);
    for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
	if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) {
	    dv = devsw[i];
	    break;
	}
    }
    if (dv == NULL)
	return(ENOENT);
    idev = malloc(sizeof(struct disk_devdesc));
    err = 0;
    np = (devspec + strlen(dv->dv_name));
    switch(dv->dv_type) {
    case DEVT_NONE:			
	break;
    case DEVT_DISK:
	err = disk_parsedev(idev, np, path);
	if (err != 0)
	    goto fail;
	break;
    case DEVT_CD:
    case DEVT_NET:
	unit = 0;
	if (*np && (*np != ':')) {
	    unit = strtol(np, (char **)&cp, 0);	
	    if (cp == np) {
		err = EUNIT;
		goto fail;
	    }
	} else {
		cp = np;
	}
	if (*cp && (*cp != ':')) {
	    err = EINVAL;
	    goto fail;
	}
	idev->d_unit = unit;
	if (path != NULL)
	    *path = (*cp == 0) ? cp : cp + 1;
	break;
    case DEVT_ZFS:
#if defined(USERBOOT_ZFS_SUPPORT)
	    err = zfs_parsedev((struct zfs_devdesc *)idev, np, path);
	    if (err != 0)
		    goto fail;
	    break;
#else
#endif
    default:
	err = EINVAL;
	goto fail;
    }
    idev->d_dev = dv;
    idev->d_type = dv->dv_type;
    if (dev == NULL) {
	free(idev);
    } else {
	*dev = idev;
    }
    return(0);
 fail:
    free(idev);
    return(err);
}
static int userboot_parsedev ( struct disk_devdesc * * dev , const char * devspec , const char * * path ) { struct disk_devdesc * idev ; struct devsw * dv ; int i , unit , err ; const char * cp ; const char * np ; if ( strlen ( devspec ) < 2 ) return ( EINVAL ) ; for ( i = 0 , dv = NULL ; devsw [ i ] != NULL ; i ++ ) { if ( ! strncmp ( devspec , devsw [ i ] -> dv_name , strlen ( devsw [ i ] -> dv_name ) ) ) { dv = devsw [ i ] ; break ; } } if ( dv == NULL ) return ( ENOENT ) ; idev = malloc ( sizeof ( struct disk_devdesc ) ) ; err = 0 ; np = ( devspec + strlen ( dv -> dv_name ) ) ; switch ( dv -> dv_type ) { case DEVT_NONE : break ; case DEVT_DISK : err = disk_parsedev ( idev , np , path ) ; if ( err != 0 ) goto fail ; break ; case DEVT_CD : case DEVT_NET : unit = 0 ; if ( * np && ( * np != ' ' ) ) { unit = strtol ( np , ( char * * ) & cp , 0 ) ; if ( cp == np ) { err = EUNIT ; goto fail ; } } else { cp = np ; } if ( * cp && ( * cp != ' ' ) ) { err = EINVAL ; goto fail ; } idev -> d_unit = unit ; if ( path != NULL ) * path = ( * cp == 0 ) ? cp : cp + 1 ; break ; case DEVT_ZFS : #if defined ( USERBOOT_ZFS_SUPPORT ) err = zfs_parsedev ( ( struct zfs_devdesc * ) idev , np , path ) ; if ( err != 0 ) goto fail ; break ; #else #endif default : err = EINVAL ; goto fail ; } idev -> d_dev = dv ; idev -> d_type = dv -> dv_type ; if ( dev == NULL ) { free ( idev ) ; } else { * dev = idev ; } return ( 0 ) ; fail : free ( idev ) ; return ( err ) ; }
Point (dev) at an allocated device specifier matching the string version
 at the beginning of (devspec).
Point ( dev ) at an allocated device specifier matching the string version at the beginning of ( devspec ) .
/* minimum length check */ /* look for a device that matches */ /* XXX what to do here?  Do we care? */ /* get unit number if present */ /* FALLTHROUGH */