コード例 #1
0
ファイル: devicename.c プロジェクト: MattDooner/freebsd-west
/*
 * 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>]:
 *
 */
static int
i386_parsedev(struct i386_devdesc **dev, const char *devspec, const char **path)
{
    struct i386_devdesc *idev;
    struct devsw	*dv;
    int			i, unit, err;
    char		*cp;
    const char		*np;

    /* minimum length check */
    if (strlen(devspec) < 2)
        return(EINVAL);

    /* look for a device that matches */
    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 i386_devdesc));
    err = 0;
    np = (devspec + strlen(dv->dv_name));

    switch(dv->dv_type) {
    case DEVT_NONE:			/* XXX what to do here?  Do we care? */
        break;

    case DEVT_DISK:
        err = disk_parsedev((struct disk_devdesc *)idev, np, path);
        if (err != 0)
            goto fail;
        break;

    case DEVT_CD:
    case DEVT_NET:
        unit = 0;

        if (*np && (*np != ':')) {
            unit = strtol(np, &cp, 0);	/* get unit number if present */
            if (cp == np) {
                err = EUNIT;
                goto fail;
            }
        } else {
            cp = (char *)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:
        err = zfs_parsedev((struct zfs_devdesc *)idev, np, path);
        if (err != 0)
            goto fail;
        break;
    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);
}
コード例 #2
0
ファイル: devicename.c プロジェクト: 2trill2spill/freebsd
/*
 * 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:
 *
 * fs<unit>:
 */
static int
efi_parsedev(struct devdesc **dev, const char *devspec, const char **path)
{
	struct devdesc *idev;
	struct devsw *dv;
	int i, unit, err;
	char *cp;
	const char *np;

	/* minimum length check */
	if (strlen(devspec) < 2)
		return (EINVAL);

	/* look for a device that matches */
	for (i = 0; devsw[i] != NULL; i++) {
		dv = devsw[i];
		if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
			break;
	}
	if (devsw[i] == NULL)
		return (ENOENT);

	np = devspec + strlen(dv->dv_name);
	idev = NULL;
	err = 0;

	switch (dv->dv_type) {
	case DEVT_NONE:
		break;

	case DEVT_DISK:
		idev = malloc(sizeof(struct disk_devdesc));
		if (idev == NULL)
			return (ENOMEM);

		err = disk_parsedev((struct disk_devdesc *)idev, np, path);
		if (err != 0)
			goto fail;
		break;

#ifdef EFI_ZFS_BOOT
	case DEVT_ZFS:
		idev = malloc(sizeof(struct zfs_devdesc));
		if (idev == NULL)
			return (ENOMEM);

		err = zfs_parsedev((struct zfs_devdesc*)idev, np, path);
		if (err != 0)
			goto fail;
		break;
#endif
	default:
		idev = malloc(sizeof(struct devdesc));
		if (idev == NULL)
			return (ENOMEM);

		unit = 0;
		cp = (char *)np;

		if (*np != '\0' && *np != ':') {
			errno = 0;
			unit = strtol(np, &cp, 0);
			if (errno != 0 || cp == np) {
				err = EUNIT;
				goto fail;
			}
		}
		if (*cp != '\0' && *cp != ':') {
			err = EINVAL;
			goto fail;
		}

		idev->d_unit = unit;
		if (path != NULL)
			*path = (*cp == 0) ? cp : cp + 1;
		break;
	}

	idev->d_dev = dv;
	idev->d_type = dv->dv_type;

	if (dev != NULL)
		*dev = idev;
	else
		free(idev);
	return (0);

fail:
	free(idev);
	return (err);
}