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