119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * base_device.c
319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Return the "base device" given a particular device; this is used to
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * assure that we only fsck one partition on a particular drive at any
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * one time.  Otherwise, the disk heads will be seeking all over the
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * place.  If the base device can not be determined, return NULL.
83984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * The base_device() function returns an allocated string which must
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * be freed.
113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Written by Theodore Ts'o, <tytso@mit.edu>
133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 2000 Theodore Ts'o.
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header%
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License.
1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header%
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_UNISTD_H
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h>
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_STDLIB_H
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h>
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "fsck.h"
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * pathames.
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char *devfs_hier[] = {
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	"host", "bus", "target", "lun", 0
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectchar *base_device(const char *device)
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char *str, *cp;
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char **hier, *disk;
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int len;
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	str = malloc(strlen(device)+1);
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!str)
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return NULL;
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	strcpy(str, device);
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	cp = str;
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Skip over /dev/; if it's not present, give up. */
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strncmp(cp, "/dev/", 5) != 0)
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto errout;
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	cp += 5;
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Skip over /dev/dsk/... */
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strncmp(cp, "dsk/", 4) == 0)
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp += 4;
613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * For md devices, we treat them all as if they were all
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * on one disk, since we don't know how to parallelize them.
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (cp[0] == 'm' && cp[1] == 'd') {
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*(cp+2) = 0;
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return str;
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Handle DAC 960 devices */
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strncmp(cp, "rd/", 3) == 0) {
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp += 3;
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (cp[0] != 'c' || cp[2] != 'd' ||
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    !isdigit(cp[1]) || !isdigit(cp[3]))
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto errout;
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*(cp+4) = 0;
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return str;
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Now let's handle /dev/hd* and /dev/sd* devices.... */
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) {
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp += 2;
8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/* If there's a single number after /dev/hd, skip it */
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (isdigit(*cp))
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			cp++;
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/* What follows must be an alpha char, or give up */
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!isalpha(*cp))
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto errout;
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*(cp + 1) = 0;
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return str;
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Now let's handle devfs (ugh) names */
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	len = 0;
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strncmp(cp, "ide/", 4) == 0)
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		len = 4;
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strncmp(cp, "scsi/", 5) == 0)
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		len = 5;
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (len) {
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp += len;
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/*
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * Now we proceed down the expected devfs hierarchy.
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * i.e., .../host1/bus2/target3/lun4/...
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * If we don't find the expected token, followed by
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * some number of digits at each level, abort.
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 */
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (hier = devfs_hier; *hier; hier++) {
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			len = strlen(*hier);
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (strncmp(cp, *hier, len) != 0)
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto errout;
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			cp += len;
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			while (*cp != '/' && *cp != 0) {
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (!isdigit(*cp))
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					goto errout;
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				cp++;
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			cp++;
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*(cp - 1) = 0;
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return str;
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Now handle devfs /dev/disc or /dev/disk names */
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	disk = 0;
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strncmp(cp, "discs/", 6) == 0)
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		disk = "disc";
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else if (strncmp(cp, "disks/", 6) == 0)
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		disk = "disk";
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (disk) {
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp += 6;
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strncmp(cp, disk, 4) != 0)
13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto errout;
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp += 4;
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while (*cp != '/' && *cp != 0) {
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!isdigit(*cp))
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto errout;
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			cp++;
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*cp = 0;
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return str;
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecterrout:
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	free(str);
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return NULL;
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main(int argc, char** argv)
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *base;
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char  buf[256], *cp;
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (1) {
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fgets(buf, sizeof(buf), stdin) == NULL)
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp = strchr(buf, '\n');
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (cp)
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*cp = 0;
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp = strchr(buf, '\t');
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (cp)
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*cp = 0;
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		base = base_device(buf);
16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("%s\t%s\n", buf, base ? base : "NONE");
16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(0);
16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
170