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