de58525957116f6c2c02902db46caf56e9af4229
[openafs.git] / src / vol / devname.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #include <ctype.h>
16
17 #include <rx/xdr.h>
18 #include <rx/rx_queue.h>
19 #include <afs/afsint.h>
20
21 #if !defined(AFS_SGI_ENV)
22 #ifdef  AFS_OSF_ENV
23 #include <ufs/fs.h>
24 #else /* AFS_OSF_ENV */
25 #ifdef AFS_VFSINCL_ENV
26 #define VFS
27 #ifdef  AFS_SUN5_ENV
28 #include <sys/fs/ufs_fs.h>
29 #else
30 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
31 #include <ufs/ufs/dinode.h>
32 #include <ufs/ffs/fs.h>
33 #else
34 #include <ufs/fs.h>
35 #endif
36 #endif
37 #else /* AFS_VFSINCL_ENV */
38 #if !defined(AFS_AIX_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_DARWIN_ENV)
39 #include <sys/fs.h>
40 #endif
41 #endif /* AFS_VFSINCL_ENV */
42 #endif /* AFS_OSF_ENV */
43 #endif /* AFS_SGI_ENV */
44 #include <sys/file.h>
45 #ifdef  AFS_AIX_ENV
46 #include <sys/vfs.h>
47 #else
48 #ifdef  AFS_HPUX_ENV
49 #include <mntent.h>
50 #else
51 #if     defined(AFS_SUN_ENV) || defined(AFS_SUN5_ENV)
52 #ifdef  AFS_SUN5_ENV
53 #include <sys/mnttab.h>
54 #include <sys/mntent.h>
55 #else
56 #include <mntent.h>
57 #endif
58 #else
59 #if defined(AFS_SGI_ENV)
60 #include <mntent.h>
61 #else
62 #ifdef AFS_LINUX22_ENV
63 #include <mntent.h>
64 #else
65 #include <fstab.h>
66 #endif
67 #endif
68 #endif /* AFS_SGI_ENV */
69 #endif /* AFS_HPUX_ENV */
70 #endif
71 #include <sys/wait.h>
72 #include <setjmp.h>
73
74 #include "ihandle.h"
75 #include "partition.h"
76
77 /* ensure that we don't have a "/" instead of a "/dev/rxd0a" type of device.
78  * returns pointer to static storage; copy it out quickly!
79  */
80 char *
81 vol_DevName(dev_t adev, char *wpath)
82 {
83     static char pbuffer[128];
84     char pbuf[128], *ptr;
85 #ifdef  AFS_SUN5_ENV
86     struct mnttab mnt;
87     FILE *mntfile;
88 #else
89 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
90     struct mntent *mntent;
91     FILE *mfd;
92 #else
93     struct fstab *fsent;
94 #endif
95 #endif
96 #ifdef  AFS_AIX_ENV
97     int nmounts;
98     struct vmount *vmountp;
99 #endif
100
101 #ifdef  AFS_AIX_ENV
102     if ((nmounts = getmount(&vmountp)) <= 0) {
103         return NULL;
104     }
105     for (; nmounts;
106          nmounts--, vmountp =
107          (struct vmount *)((int)vmountp + vmountp->vmt_length)) {
108         char *part = vmt2dataptr(vmountp, VMT_STUB);
109 #else
110 #ifdef  AFS_SUN5_ENV
111     if (!(mntfile = fopen(MNTTAB, "r"))) {
112         return NULL;
113     }
114     while (!getmntent(mntfile, &mnt)) {
115         char *part = mnt.mnt_mountp;
116 #else
117 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
118 #ifdef AFS_LINUX22_ENV
119     if ((mfd = setmntent("/proc/mounts", "r")) == NULL) {
120         if ((mfd = setmntent("/etc/mtab", "r")) == NULL) {
121             return NULL;
122         }
123     }
124 #else
125     if ((mfd = setmntent(MOUNTED /*MNTTAB*/, "r")) == NULL) {
126         return NULL;
127     }
128 #endif
129     while ((mntent = getmntent(mfd))) {
130         char *part = mntent->mnt_dir;
131 #else
132     setfsent();
133     while ((fsent = getfsent())) {
134         char *part = fsent->fs_file;
135 #endif
136 #endif /* AFS_SGI_ENV */
137 #endif
138         struct stat status;
139 #ifdef  AFS_AIX_ENV
140         if (vmountp->vmt_flags & (MNT_READONLY | MNT_REMOVABLE | MNT_REMOTE))
141             continue;           /* Ignore any "special" partitions */
142 #else
143 #ifdef  AFS_SUN5_ENV
144         /* Ignore non ufs or non read/write partitions */
145         if ((strcmp(mnt.mnt_fstype, "ufs") != 0)
146             || (strncmp(mnt.mnt_mntopts, "ro,ignore", 9) == 0))
147             continue;
148 #else
149 #if defined(AFS_LINUX22_ENV)
150         if (strcmp(mntent->mnt_type, "ext2"))
151             continue;
152 #else
153 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV)
154         if (!hasmntopt(mntent, MNTOPT_RW))
155             continue;
156 #else
157         if (strcmp(fsent->fs_type, "rw") != 0)
158             continue;           /* Ignore non read/write partitions */
159 #endif /* AFS_LINUX22_ENV */
160 #endif /* AFS_SGI_ENV */
161 #endif
162 #endif
163         /* Only keep track of "/vicepx" partitions since it can get hairy when NFS mounts are involved.. */
164         if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
165             continue;           /* Non /vicepx; ignore */
166         }
167         if (stat(part, &status) == -1) {
168             continue;
169         }
170 #if !defined(AFS_SGI_XFS_IOPS_ENV) && !defined(AFS_LINUX22_ENV) && !defined(AFS_DARWIN_ENV)
171         if ((status.st_ino !=
172              ROOTINO) /*|| ((status.st_mode & S_IFMT) != S_IFBLK) */ ) {
173             continue;
174         }
175 #endif
176         if (status.st_dev == adev) {
177 #ifdef  AFS_AIX_ENV
178             strcpy(pbuffer, vmt2dataptr(vmountp, VMT_OBJECT));
179 #else
180 #ifdef  AFS_SUN5_ENV
181             strcpy(pbuffer, mnt.mnt_special);
182 #else
183 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
184             strcpy(pbuffer, mntent->mnt_fsname);
185 #else
186             strcpy(pbuffer, fsent->fs_spec);
187 #endif
188 #endif /* AFS_SGI_ENV */
189 #endif
190             if (wpath) {
191                 strcpy(pbuf, pbuffer);
192                 ptr = (char *)strrchr(pbuf, OS_DIRSEPC);
193                 if (ptr) {
194                     *ptr = '\0';
195                     strcpy(wpath, pbuf);
196                 } else
197                     return NULL;
198             }
199             ptr = (char *)strrchr(pbuffer, OS_DIRSEPC);
200             if (ptr) {
201                 strcpy(pbuffer, ptr + 1);
202                 return pbuffer;
203             } else
204                 return NULL;
205         }
206     }
207 #ifdef  AFS_SUN5_ENV
208     (void)fclose(mntfile);
209 #else
210 #if defined(AFS_SGI_ENV) || defined(AFS_SUN_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX22_ENV)
211     endmntent(mfd);
212 #else
213 #ifndef AFS_AIX_ENV
214     endfsent();
215 #endif
216 #endif
217 #endif /* AFS_SGI_ENV */
218     return NULL;
219 }
220
221 /* Search for the raw device name. Will put an "r" in front of each
222  * directory and file entry of the pathname until we find a character
223  * device.
224  */
225 char *
226 afs_rawname(char *devfile)
227 {
228     static char rawname[100];
229     struct stat statbuf;
230     int code, i;
231
232     i = strlen(devfile);
233     while (i >= 0) {
234         strcpy(rawname, devfile);
235         if (devfile[i] == OS_DIRSEPC) {
236             rawname[i + 1] = 'r';
237             rawname[i + 2] = 0;
238             strcat(rawname, &devfile[i + 1]);
239         }
240
241         code = stat(rawname, &statbuf);
242         if (!code && S_ISCHR(statbuf.st_mode))
243             return rawname;
244
245         while ((--i >= 0) && (devfile[i] != OS_DIRSEPC));
246     }
247
248     return NULL;
249 }