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