~ubuntu-branches/ubuntu/quantal/util-linux/quantal

« back to all changes in this revision

Viewing changes to fsck/base_device.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-06-20 22:31:50 UTC
  • mfrom: (1.6.3 upstream) (4.5.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110620223150-lz8wrv0946ihcz3z
Tags: 2.19.1-2ubuntu1
* Merge from Debian unstable, remaining changes:
  - Build for multiarch.
  - Add pre-depends on multiarch-support.
  - configure.ac: don't try to be clever about extracting a path name from
    $libdir to append to /usr in a way that's not overridable; instead,
    reuse the built-in configurable libexecdir.
  - Fix up the .pc.in files to know about libexecdir, so our substitutions
    don't leave us with unusable pkg-config files.
  - Install custom blkid.conf to use /dev/.blkid.tab since we don't
    expect device names to survive a reboot
  - Mention mountall(8) in fstab(5) manpages, along with its special
    options.
  - Since upstart is required in Ubuntu, the hwclock.sh init script is not
    called on startup and the hwclockfirst.sh init script is removed.
  - Drop depends on initscripts for the above.
  - Replace hwclock udev rule with an Upstart job.
  - For the case where mount is called with a directory to mount, look
    that directory up in mountall's /lib/init/fstab if we couldn't find
    it mentioned anywhere else.  This means "mount /proc", "mount /sys",
    etc. work.
  - mount.8 points to the cifs-utils package, not the obsolete smbfs one. 
* Dropped changes:
  - mount.preinst: lsb_release has been fixed in lucid and above to be
    usable without configuration, so we don't have to diverge from Debian
    here anymore.
* Changes merged upstream:
  - sfdisk support for '+' with '-N'
  - mount/umount.c: fix a segfault on umount with empty mtab entry
  - Fix arbitrary unmount with fuse security issue

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * base_device.c
3
 
 *
4
 
 * Return the "base device" given a particular device; this is used to
5
 
 * assure that we only fsck one partition on a particular drive at any
6
 
 * one time.  Otherwise, the disk heads will be seeking all over the
7
 
 * place.  If the base device can not be determined, return NULL.
8
 
 *
9
 
 * The base_device() function returns an allocated string which must
10
 
 * be freed.
11
 
 *
12
 
 * Written by Theodore Ts'o, <tytso@mit.edu>
13
 
 *
14
 
 * Copyright (C) 2000 Theodore Ts'o.
15
 
 *
16
 
 * %Begin-Header%
17
 
 * This file may be redistributed under the terms of the GNU Public
18
 
 * License.
19
 
 * %End-Header%
20
 
 */
21
 
#include <stdio.h>
22
 
#if HAVE_UNISTD_H
23
 
#include <unistd.h>
24
 
#endif
25
 
#if HAVE_STDLIB_H
26
 
#include <stdlib.h>
27
 
#endif
28
 
#include <ctype.h>
29
 
#include <string.h>
30
 
 
31
 
#include "fsck.h"
32
 
 
33
 
/*
34
 
 * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3
35
 
 * pathames.
36
 
 */
37
 
static const char *devfs_hier[] = {
38
 
        "host", "bus", "target", "lun", 0
39
 
};
40
 
 
41
 
char *base_device(const char *device)
42
 
{
43
 
        char *str, *cp;
44
 
        const char **hier, *disk;
45
 
        int len;
46
 
 
47
 
        str = malloc(strlen(device)+1);
48
 
        if (!str)
49
 
                return NULL;
50
 
        strcpy(str, device);
51
 
        cp = str;
52
 
 
53
 
        /* Skip over /dev/; if it's not present, give up. */
54
 
        if (strncmp(cp, "/dev/", 5) != 0)
55
 
                goto errout;
56
 
        cp += 5;
57
 
 
58
 
        /* Skip over /dev/dsk/... */
59
 
        if (strncmp(cp, "dsk/", 4) == 0)
60
 
                cp += 4;
61
 
 
62
 
        /*
63
 
         * For md devices, we treat them all as if they were all
64
 
         * on one disk, since we don't know how to parallelize them.
65
 
         */
66
 
        if (cp[0] == 'm' && cp[1] == 'd') {
67
 
                *(cp+2) = 0;
68
 
                return str;
69
 
        }
70
 
 
71
 
        /* Handle DAC 960 devices */
72
 
        if (strncmp(cp, "rd/", 3) == 0) {
73
 
                cp += 3;
74
 
                if (cp[0] != 'c' || cp[2] != 'd' ||
75
 
                    !isdigit(cp[1]) || !isdigit(cp[3]))
76
 
                        goto errout;
77
 
                *(cp+4) = 0;
78
 
                return str;
79
 
        }
80
 
 
81
 
        /* Now let's handle /dev/hd* and /dev/sd* devices.... */
82
 
        if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) {
83
 
                cp += 2;
84
 
                /* If there's a single number after /dev/hd, skip it */
85
 
                if (isdigit(*cp))
86
 
                        cp++;
87
 
                /* What follows must be an alpha char, or give up */
88
 
                if (!isalpha(*cp))
89
 
                        goto errout;
90
 
                *(cp + 1) = 0;
91
 
                return str;
92
 
        }
93
 
 
94
 
        /* Now let's handle devfs (ugh) names */
95
 
        len = 0;
96
 
        if (strncmp(cp, "ide/", 4) == 0)
97
 
                len = 4;
98
 
        if (strncmp(cp, "scsi/", 5) == 0)
99
 
                len = 5;
100
 
        if (len) {
101
 
                cp += len;
102
 
                /*
103
 
                 * Now we proceed down the expected devfs hierarchy.
104
 
                 * i.e., .../host1/bus2/target3/lun4/...
105
 
                 * If we don't find the expected token, followed by
106
 
                 * some number of digits at each level, abort.
107
 
                 */
108
 
                for (hier = devfs_hier; *hier; hier++) {
109
 
                        len = strlen(*hier);
110
 
                        if (strncmp(cp, *hier, len) != 0)
111
 
                                goto errout;
112
 
                        cp += len;
113
 
                        while (*cp != '/' && *cp != 0) {
114
 
                                if (!isdigit(*cp))
115
 
                                        goto errout;
116
 
                                cp++;
117
 
                        }
118
 
                        cp++;
119
 
                }
120
 
                *(cp - 1) = 0;
121
 
                return str;
122
 
        }
123
 
 
124
 
        /* Now handle devfs /dev/disc or /dev/disk names */
125
 
        disk = 0;
126
 
        if (strncmp(cp, "discs/", 6) == 0)
127
 
                disk = "disc";
128
 
        else if (strncmp(cp, "disks/", 6) == 0)
129
 
                disk = "disk";
130
 
        if (disk) {
131
 
                cp += 6;
132
 
                if (strncmp(cp, disk, 4) != 0)
133
 
                        goto errout;
134
 
                cp += 4;
135
 
                while (*cp != '/' && *cp != 0) {
136
 
                        if (!isdigit(*cp))
137
 
                                goto errout;
138
 
                        cp++;
139
 
                }
140
 
                *cp = 0;
141
 
                return str;
142
 
        }
143
 
 
144
 
errout:
145
 
        free(str);
146
 
        return NULL;
147
 
}
148
 
 
149
 
#ifdef DEBUG
150
 
int main(int argc, char** argv)
151
 
{
152
 
        const char *base;
153
 
        char  buf[256], *cp;
154
 
 
155
 
        while (1) {
156
 
                if (fgets(buf, sizeof(buf), stdin) == NULL)
157
 
                        break;
158
 
                cp = strchr(buf, '\n');
159
 
                if (cp)
160
 
                        *cp = 0;
161
 
                cp = strchr(buf, '\t');
162
 
                if (cp)
163
 
                        *cp = 0;
164
 
                base = base_device(buf);
165
 
                printf("%s\t%s\n", buf, base ? base : "NONE");
166
 
        }
167
 
        exit(0);
168
 
}
169
 
#endif