2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #if defined(AFS_DUX40_ENV) || (defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)) || defined(AFS_SUN54_ENV)
17 #if defined AFS_DUX40_ENV
18 #define OSVERS "DUX 4.0D"
20 #if defined(AFS_SUN54_ENV)
21 #define OSVERS "SunOS 5.6"
23 #define OSVERS "SunOS 4.1.1"
26 #include <sys/types.h>
28 #include <afs/afsint.h>
29 #include <sys/param.h>
32 #include <sys/fs/ufs_fs.h>
38 #include <sys/mount.h>
42 #endif /* ITIMER_REAL */
44 #ifdef AFS_VFSINCL_ENV
45 #include <sys/vnode.h>
47 #include <sys/fs/ufs_inode.h>
49 #include <ufs/inode.h>
51 #else /* AFS_VFSINCL_ENV */
53 #include <ufs/inode.h>
55 #include <sys/inode.h>
57 #endif /* AFS_VFSINCL_ENV */
60 #include <sys/lockf.h>
64 #include <checklist.h>
67 #include <sys/mnttab.h>
68 #include <sys/mntent.h>
69 #include <sys/vfstab.h>
76 #include <afs/osi_inode.h>
80 #include <partition.h>
85 int icount = 0, iarraysize = 0, *iarray;
87 char *rawname(), *unrawname(), *vol_DevName(), *blockcheck();
89 int force = 0, verbose = 0, unconv = 0;
115 printf("Cannot open %s: error %d\n", path, errno);
119 while (de = readdir(d)) {
120 if (iarraysize == 0) {
122 iarray = (int *)malloc(iarraysize * sizeof(int));
124 if (icount >= iarraysize) {
126 iarray = (int *)realloc(iarray, iarraysize * sizeof(int));
128 iarray[icount] = de->d_ino;
131 if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0))
136 strcat(p, de->d_name);
138 code = stat(p, &stats);
140 printf("Cannot stat %s: error %d\n", path, errno);
143 if (S_ISDIR(stats.st_mode)) {
144 code = BuildInodes(p);
157 struct cmd_syndesc *as;
165 struct cmd_syndesc *as;
171 #if defined(AFS_SUN54_ENV)
175 struct cmd_syndesc *as;
177 register struct cmd_item *ti;
179 afs_int32 haspart = 0, hasDevice = 0;
182 if (as->parms[1].items)
186 if (as->parms[2].items)
193 ("Unconverts from a %s AFS partition to a pre-%s compatible format.\n\n",
197 ("Converts a pre-%s AFS partition to a %s compatible format.\n\n",
202 ("*** Must use the '-force' option for command to have effect! ***\n");
205 ("*** Use the '-verbose' option to report what will be converted ***\n");
210 for (ti = as->parms[0].items; ti; ti = ti->next) {
212 char *namep = ti->data;
216 if ((fsent = fopen(VFSTAB, "r")) == NULL) {
217 printf("Unable to open %s ( errno = %d)\n", VFSTAB, errno);
220 while (!getvfsent(fsent, &mnt)) {
221 char *part = mnt.vfs_mountp;
226 if (!strncmp(namep, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
227 if (!strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
228 if (!strncmp(part, namep, strlen(part) + 1)) {
229 if (dname = mnt.vfs_fsckdev) {
230 printf("ProcessFileSys %s %s\n", dname, namep);
231 ProcessFileSys(dname, namep);
240 printf("Unknown input AFS partition name or device: %s\n", namep);
244 /* if raw devices are specified */
245 for (ti = as->parms[3].items; ti; ti = ti->next) {
246 char *namep = ti->data;
250 if (!CheckMountedDevice(namep)) {
251 printf("Device %s may be mounted, aborting...\n", namep);
254 ProcessFileSys(namep, namep);
258 if (!haspart && !hasDevice) {
262 if ((fsent = fopen(VFSTAB, "r")) == NULL) {
263 printf("Unable to open %s ( errno = %d)\n", VFSTAB, errno);
266 while (!getvfsent(fsent, &mnt)) {
267 char *part = mnt.vfs_mountp;
272 if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE) == 0) {
273 if (dname = mnt.vfs_fsckdev)
274 ProcessFileSys(dname, part);
281 ("No file system partitions named %s* found; not processed\n",
282 VICE_PARTITION_PREFIX);
286 #else /* AFS_SUN54_ENV */
289 struct cmd_syndesc *as;
291 register struct cmd_item *ti;
293 afs_int32 haspart = 0;
295 if (as->parms[1].items)
299 if (as->parms[2].items)
306 ("Unconverts from a %s AFS partition to a pre-%s compatible format.\n\n",
310 ("Converts a pre-%s AFS partition to a %s compatible format.\n\n",
315 ("*** Must use the '-force' option for command to have effect! ***\n");
318 ("*** Use the '-verbose' option to report what will be converted ***\n");
323 for (ti = as->parms[0].items; ti; ti = ti->next) {
325 char *namep = ti->data;
330 while (fsent = getfsent()) {
331 char *part = fsent->fs_file;
333 if (!strncmp(namep, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
334 if (!strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
335 if (!strncmp(part, namep, strlen(part) + 1)) {
336 if (dname = unrawname(fsent->fs_spec)) {
337 ProcessFileSys(dname, namep);
344 if (!rawname(namep) || !unrawname(namep))
346 if (!strcmp(fsent->fs_spec, rawname(namep))
347 || !strcmp(fsent->fs_spec, unrawname(namep))) {
348 if (dname = unrawname(fsent->fs_spec)) {
349 ProcessFileSys(dname, fsent->fs_file);
357 printf("Unknown input AFS partition name or device: %s\n", namep);
366 while (fsent = getfsent()) {
367 char *part = fsent->fs_file;
369 if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE) == 0) {
370 if (dname = unrawname(fsent->fs_spec)) {
371 ProcessFileSys(dname, part);
379 ("No file system partitions named %s* found; not processed\n",
380 VICE_PARTITION_PREFIX);
383 #endif /* AFS_SUN54_ENV */
386 #include "AFS_component_version_number.c"
391 register struct cmd_syndesc *ts;
394 if (geteuid() != 0) {
395 printf("must be run as root; sorry\n");
399 ts = cmd_CreateSyntax("convert", ConvCmd, 0,
400 "Convert to DUX 4.0D format");
402 #if defined(AFS_SUN54_ENV)
403 ts = cmd_CreateSyntax("convert", ConvCmd, 0,
404 "Convert to AFS SunOS 5.6 format");
406 ts = cmd_CreateSyntax("convert", ConvCmd, 0,
407 "Convert to AFS 4.1.1 format");
410 cmd_AddParm(ts, "-part", CMD_LIST, CMD_OPTIONAL, "AFS partition name");
411 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose mode");
412 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
413 "Safeguard enforce switch");
414 cmd_AddParm(ts, "-device", CMD_LIST, CMD_OPTIONAL, "AFS raw device name");
416 ts = cmd_CreateSyntax("unconvert", UnConvCmd, 0,
417 "Convert back from OSF 4.0D to earlier formats");
419 #if defined(AFS_SUN54_ENV)
420 ts = cmd_CreateSyntax("unconvert", UnConvCmd, 0,
421 "Convert back from AFS SunOS 5.6 to earlier formats");
423 ts = cmd_CreateSyntax("unconvert", UnConvCmd, 0,
424 "Convert back from AFS 4.1.1 to earlier formats");
427 cmd_AddParm(ts, "-part", CMD_LIST, CMD_OPTIONAL, "AFS partition name");
428 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose mode");
429 cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
430 "Safeguard enforce switch");
431 cmd_AddParm(ts, "-device", CMD_LIST, CMD_OPTIONAL, "AFS raw device name");
433 code = cmd_Dispatch(argc, argv);
438 ProcessFileSys(dname, path)
441 struct stat status, stat1;
442 #if !defined(AFS_SUN54_ENV)
443 struct ufs_args ufsargs;
445 char devbuffer[120], *devname;
446 int i, j, mounted = 0, code;
448 if (stat(path, &status) == -1) {
449 printf("Couldn't find file system \"%s\"\n", path);
452 if (status.st_ino == ROOTINODE) {
455 ("Partition %s is mounted; only unmounted partitions are processed\n",
461 strcpy(devbuffer, dname);
463 #if !defined(AFS_SUN54_ENV)
464 EnsureDevice(devname);
468 ufsargs.fspec = devname;
469 code = mount(MOUNT_UFS, path, 0, &ufsargs);
471 #if defined(AFS_SUN54_ENV)
474 ufsargs.fspec = devname;
475 code = mount("4.2", path, M_NEWTYPE, &ufsargs);
479 printf("Couldn't mount %s on %s (err=%d)\n", devname, path,
485 if (stat(path, &status) == -1) {
486 printf("Couldn't find file system \"%s\"\n", path);
491 code = BuildInodes(path);
493 printf("Couldn't generate list of all inodes in directory %s\n",
498 qsort(iarray, icount, sizeof(int), sortinodes);
501 #if !defined(AFS_SUN54_ENV)
502 if (!(devname = vol_DevName(status.st_dev))) {
503 printf("Couldn't get devname for %d\n", status.st_dev);
508 if (ProcessAfsInodes(devname, path) == -1)
509 printf("Unable to get inodes for \"%s\"; not processed\n", path);
519 ProcessAfsInodes(devname, partition)
520 char *devname, *partition;
526 int pfd, i, c, e, bufsize, cnt = 0, mod = 0, wcnt = 0, ccnt = 0, ncnt;
527 FILE *inodeFile = NULL;
529 struct dinode *inodes = NULL, *einodes, *p;
534 #if defined(AFS_SUN54_ENV)
535 sprintf(rdev, "%s", devname);
537 sprintf(rdev, "/dev/r%s", devname);
539 pfd = open(rdev, O_RDWR);
541 printf("Could not read device %s to get inode list\n", rdev);
542 printf("errno %d: %s\n", errno, strerror(errno));
545 if (bread(pfd, super.block, SBLOCK, SBSIZE) == -1) {
546 printf("Unable to read superblock, partition %s\n", partition);
551 * run a few consistency checks of the superblock
552 * (Cribbed from vfsck)
554 if ((super.fs.fs_magic != FS_MAGIC) || (super.fs.fs_ncg < 1)
555 || (super.fs.fs_cpg < 1)
556 || (super.fs.fs_ncg * super.fs.fs_cpg < super.fs.fs_ncyl
557 || (super.fs.fs_ncg - 1) * super.fs.fs_cpg >= super.fs.fs_ncyl)
558 || (super.fs.fs_sbsize > SBSIZE)) {
560 ("There's something wrong with the superblock for partition %s; run vfsck\n",
564 bufsize = super.fs.fs_ipg * sizeof(struct dinode);
565 if (!(inodes = (struct dinode *)malloc(bufsize))) {
566 printf("Unable to allocate enough memory to scan inodes; help!\n");
569 einodes = (struct dinode *)(((char *)inodes) + bufsize);
570 printf("Processing all AFS inodes on partition %s (device %s)...\n",
572 for (c = 0; c < super.fs.fs_ncg; c++) {
574 #if defined(AFS_SUN54_ENV)
579 i = c * super.fs.fs_ipg;
580 e = i + super.fs.fs_ipg;
582 dblk1 = fsbtodb(&super.fs, itod(&super.fs, i));
583 code = lseek(pfd, (off_t) ((off_t) dblk1 * DEV_BSIZE), L_SET);
585 #if defined(AFS_SUN54_ENV)
586 f1 = fsbtodb(&super.fs, itod(&super.fs, i));
587 off = (offset_t) f1 << DEV_BSHIFT;
588 code = llseek(pfd, off, L_SET);
591 lseek(pfd, dbtob(fsbtodb(&super.fs, itod(&super.fs, i))), L_SET);
595 printf("Error reading inodes for partition %s; run vfsck\n",
597 printf("%d: %s\n", errno, strerror(errno));
598 #if defined(AFS_SUN54_ENV)
599 printf("file number = %d; offset = %ld\n", pfd, off);
601 printf("file number = %d\n", pfd);
606 wcnt = ncnt = mod = 0;
607 code = read(pfd, inodes, bufsize);
608 if (code != bufsize) {
609 printf("Error reading inodes for partition %s; run vfsck\n",
612 printf("errno %d: %s\n", errno, strerror(errno));
617 /* Step through each inode */
618 for (p = inodes; p < einodes && i < e; i++, p++)
621 afs_uint32 v1, v2, v3, v4;
622 afs_uint32 volid, vnode, uniq, vers;
623 afs_uint32 type, rwvol;
627 if ((p->di_mode & IFMT) != IFREG) {
628 /* This inode is not an AFS inode so
629 * zero out all the spare fields.
632 if (!(p->di_flags & IC_PROPLIST)) {
635 if (!(p->di_flags & IC_XUID)) {
638 if (!(p->di_flags & IC_XGID)) {
646 /* printf("Inode %d: proplb=%u, uid=%u, bcuid=0x%x, bcgid=0x%x, gid=0x%x\n",
647 * i , p->di_proplb, p->di_uid, p->di_bcuid, p->di_bcgid,
651 if (unconv) { /*unconvert */
652 /* Check if the inode is not a DUX40D AFS inode */
653 if (p->di_proplb != VICEMAGIC
654 || (p->di_flags & IC_PROPLIST)) {
657 printf(" AFS Inode %d: already unconverted\n",
664 v3 = ((u_int) (p->di_bcuid)) << 16 |
665 ((u_int) (p->di_bcgid));
667 /* We have a sorted list of ufs inodes. Is it one of these */
668 while ((istep < icount) && (i > iarray[istep])) {
671 if ((istep < icount) && (i == iarray[istep])) {
672 /* Yes, its a ufs inode */
674 printf(" Inode %d: Not an AFS Inode\n", i);
678 /* Is it not an AFS inode. !IS_VICEMAGIC check */
681 printf("Warning: Inode %d: Unreferenced inode\n",
683 continue; /* skip, making no change */
687 if (((v2 >> 3) == 0x1fffffff) && (v2 & 0x3)) {
688 special = 1; /* INODESPECIAL */
693 (" %s AFS Inode %d: Vol=%u, RWVol=%u, Type=%d\n",
694 (force ? "Unconverting" :
695 "Would have unconverted"), i, volid, rwvol,
700 vnode = ((v2 >> 27) << 16) + (v3 & 0xffff);
701 uniq = (v2 & 0x3fffff);
703 (((v2 >> 22) & 0x1f) << 16) +
704 ((v3 >> 16) & 0xffff);
707 (" %s AFS Inode %d: RWVol=%u, VNode=%u, Uniq=%u, Vers=%u\n",
708 (force ? "Unconverting" :
709 "Would have unconverted"), i, volid, vnode,
714 /* Now unconvert the DUX40D AFS inode to the OSF30 version */
718 p->di_flags &= ~(IC_PROPLIST | IC_XUID | IC_XGID);
725 } else { /*convert */
726 if ((p->di_proplb == VICEMAGIC
727 && !(p->di_flags & IC_PROPLIST))
728 || (p->di_uid == 0 && p->di_gid == 0)
729 || (p->di_flags & (IC_XUID | IC_XGID))) {
730 /* This inode is either already converted or not an AFS inode */
731 /* We have a sorted list of ufs inodes. Is it one of these */
732 while ((istep < icount) && (i > iarray[istep])) {
735 if ((istep < icount) && (i == iarray[istep])) {
736 /* Yes, its a ufs inode */
738 printf(" Inode %d: Not an AFS Inode %s\n",
741 di_spare[2]) ? "(fixed)" : ""));
746 /* Is it a AFS inode. IS_VICEMAGIC check */
747 if ((p->di_uid || p->di_gid)
748 && !(p->di_flags & (IC_XUID | IC_XGID))) {
751 printf(" AFS Inode %d: already converted\n",
756 /* Not an AFS nor UFS inode */
757 printf("Warning: Inode %d: Unreferenced inode\n", i);
758 continue; /* skip, making no changes */
766 if (((v2 >> 3) == 0x1fffffff) && (v2 & 0x3)) {
767 special = 1; /* INODESPECIAL */
772 (" %s AFS Inode %d: Vol=%u, RWVol=%u, Type=%d\n",
773 (force ? "Converting" :
774 "Would have converted"), i, volid, rwvol,
779 vnode = ((v2 >> 27) << 16) + (v3 & 0xffff);
780 uniq = (v2 & 0x3fffff);
782 (((v2 >> 22) & 0x1f) << 16) +
783 ((v3 >> 16) & 0xffff);
786 (" %s AFS Inode %d: RWVol=%u, VNode=%u, Uniq=%u, Vers=%u\n",
787 (force ? "Converting" :
788 "Would have converted"), i, volid,
789 (vnode & 0x1fffff), (uniq & 0x3fffff),
794 /* Now convert the OSF30 AFS inode to the DUX40D version */
795 p->di_proplb = VICEMAGIC;
798 p->di_bcuid = (u_short) (v3 >> 16);
799 p->di_bcgid = (u_short) v3;
800 p->di_flags &= ~(IC_PROPLIST);
801 p->di_flags |= (IC_XUID | IC_XGID);
809 afs_uint32 p1, p2, p3, p4;
813 #if defined(AFS_SUN56_ENV)
814 q = (quad *) & (p->di_ic.ic_lsize);
816 q = &(p->di_ic.ic_size);
820 p2 = p->di_ic.ic_flags;
822 p4 = p->di_ic.ic_uid;
823 p5 = p->di_ic.ic_gid;
825 /* the game is afoot, Dr Watson! */
826 if (!verbose && !((ccnt + cnt + ncnt) % 5000)) {
833 * Convert from a 5.6 format to a pre 5.6 format
835 if ((p2 || p3) && !p4 && (p5 == -2)) {
838 ("AFS Inode %d: Already in pre-%s AFS format (%x,%x,%x,%x,%x) ignoring..\n",
839 i, OSVERS, p1, p2, p3, p4, p5);
844 if (p5 == VICEMAGIC) {
845 /* This is a sol 2.6 AFS inode */
851 ("AFS Inode %d: %s from Sol5.6 (%x,%x,%x,%x,%x) \n",
853 (force ? "Unconverting" :
854 "Would have unconverted"), p1, p2, p3, p4,
857 q->val[0] = p->di_uid;
860 p->di_suid = UID_LONG;
861 p->di_sgid = GID_LONG;
866 if (p5 == VICEMAGIC) { /* Assume an already converted 5.6 afs inode */
869 ("AFS Inode %d: Already in %s AFS format (p1=%x,p2=%x,p3=%x,p4=%x,p5=%x); ignoring..\n",
870 i, OSVERS, p1, p2, p3, p4, p5);
875 /* for inodes created in solaris 2.4, there is a possibility
876 ** that the gid gets chopped off to an unsigned short(2 bytes)
878 if ((p2 || p3) && !p4 && ((p5 == -2)
879 || ((unsigned short)p5 ==
880 (unsigned short)-2))) {
881 /* This is a pre Sol2.6 inode */
887 ("AFS Inode %d: %s to 5.6 format (p1=%x,p2=%x,p3=%x,p4=%x, p5=%x)\n",
889 (force ? "Converting" :
890 "Would have converted"), p1, p2, p3, p4,
893 p->di_gid = VICEMAGIC;
894 p->di_uid = q->val[0];
895 p->di_suid = UID_LONG;
896 p->di_sgid = GID_LONG;
902 /* If not an AFS inode, ignore */
906 ("Non AFS Inode %d: (p1=%x,p2=%x,p3=%x, p4=%x,p5=%x) ignoring..\n",
907 i, p1, p2, p3, p4, p5);
912 if (lseek(pfd, -bufsize, SEEK_CUR) == -1) { /* Point to loc bef read */
913 printf("Error Seeking backwards %d bytes\n", bufsize);
914 printf("errno %d: %s\n", errno, strerror(errno));
917 code = write(pfd, inodes, bufsize);
918 if (code != bufsize) { /* Update inodes */
919 printf("Error writing modified inodes for partition %s\n",
922 printf("errno %d: %s\n", errno, strerror(errno));
927 (" Write %d AFS inodes and %d non-AFS inodes to disk\n",
934 printf("\n%s: %d AFS inodes %s ", partition, cnt,
935 (force ? "were" : "would have been"));
937 printf("unconverted to a pre-%s format; %d already unconverted.\n",
940 printf("converted to a %s format; %d already converted.\n", OSVERS,
955 bread(fd, buf, blk, size)
961 if (lseek(fd, (off_t) dbtob(blk), L_SET) < 0
962 || read(fd, buf, size) != size) {
963 printf("bread: lseek failed (errno = %d)\n", errno);
971 * Ensure that we don't have a "/" instead of a "/dev/rxd0a" type of device.
972 * returns pointer to static storage; copy it out quickly!
979 static char pbuffer[128];
985 /* now, look in /dev for the appropriate file */
986 dirp = opendir(dirName = "/dev");
987 while (dp = readdir(dirp)) {
988 strcpy(pbuffer, dirName);
989 strcat(pbuffer, "/");
990 strcat(pbuffer, dp->d_name);
991 if (stat(pbuffer, &tstat) != -1 && (tstat.st_mode & S_IFMT) == S_IFBLK
992 && (tstat.st_rdev == adev)) {
993 strcpy(pbuffer, dp->d_name);
999 return NULL; /* failed */
1009 if ((dp = strrchr(name, '/')) == 0)
1011 if (stat(name, &stb) < 0)
1013 if ((stb.st_mode & S_IFMT) != S_IFCHR)
1015 if (*(dp + 1) != 'r')
1017 (void)strcpy(dp + 1, dp + 2);
1025 static char rawbuf[32];
1028 if ((dp = strrchr(name, '/')) == 0)
1031 (void)strcpy(rawbuf, name);
1033 (void)strcat(rawbuf, "/r");
1034 (void)strcat(rawbuf, dp + 1);
1042 struct stat stslash, stblock, stchar;
1047 if (stat(name, &stblock) < 0) {
1049 printf("Can't stat %s\n", name);
1052 if ((stblock.st_mode & S_IFMT) == S_IFBLK) {
1053 raw = rawname(name);
1054 if (stat(raw, &stchar) < 0) {
1056 printf("Can't stat %s\n", raw);
1059 if ((stchar.st_mode & S_IFMT) == S_IFCHR) {
1062 printf("%s is not a character device\n", raw);
1065 } else if ((stblock.st_mode & S_IFMT) == S_IFCHR && !retried) {
1066 name = unrawname(name);
1070 printf("Can't make sense out of name %s\n", name);
1075 /* ensure that we don't have a "/" instead of a "/dev/rxd0a" type of device.
1076 * Overwrites abuffer with the corrected name.
1078 EnsureDevice(abuffer)
1089 code = stat(abuffer, &tstat);
1092 if (((tstat.st_mode & S_IFMT) == S_IFBLK)
1093 || ((tstat.st_mode & S_IFMT) == S_IFCHR)) {
1094 return 0; /* already a block or char device */
1096 /* otherwise, assume we've got a normal file, and we look up its device */
1097 dev = tstat.st_dev; /* remember device for this file */
1099 /* now, look in /dev for the appropriate file */
1100 dirp = opendir(dirName = "/dev");
1102 while (dp = readdir(dirp)) {
1103 strcpy(pbuffer, dirName);
1104 strcat(pbuffer, "/");
1105 strcat(pbuffer, dp->d_name);
1106 if (stat(pbuffer, &tstat) != -1 && (tstat.st_mode & S_IFMT) == S_IFBLK
1107 && (tstat.st_rdev == dev)) {
1108 strcpy(abuffer, pbuffer);
1114 return 1; /* failed */
1118 #include "AFS_component_version_number.c"
1125 ("%s: **ONLY** supported for SunOS 3.5-4.x and dux4.0D systems ...\n",
1128 #endif /* defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV) */
1130 #if defined(AFS_SUN54_ENV)
1133 ** Open the /etc/vfstab file to map the raw device name to the mountable
1134 ** device name. Then open the /etc/mnttab file to see if this mountable
1135 ** device is mounted.
1137 ** Returns 1 if the conversion process should continue, otherwise returns 0
1139 CheckMountedDevice(devName)
1140 char *devName; /* raw device name */
1142 FILE *vfsent, *mntent;
1149 if ((vfsent = fopen(VFSTAB, "r")) == NULL) {
1150 printf("Unable to open %s ( errno = %d)\n", VFSTAB, errno);
1153 while (!getvfsent(vfsent, &vnt)) {
1154 char *rawDev = vnt.vfs_fsckdev;
1155 if (rawDev && !strcmp(rawDev, devName)) {
1156 /* this is the device we are looking for */
1157 unRawDev = vnt.vfs_special;
1164 goto done; /* could not find it in /etc/vfstab */
1166 /* we found the entry in /etc/vfstab. Now we open /etc/mnnttab and
1167 ** verify that it is not mounted
1169 if ((mntent = fopen(MNTTAB, "r")) == NULL) {
1170 printf("Unable to open %s ( errno = %d)\n", VFSTAB, errno);
1174 while (!getmntent(mntent, &mnt)) {
1175 char *resource = mnt.mnt_special;
1176 if (resource && !strcmp(resource, unRawDev)) {
1184 /* if we found an entry in the /etc/mnttab file, then this
1185 ** device must be mounted
1191 ("Device %s may be mounted. Can corrupt data. Continue anyway(y/n)?",
1195 YesNo = getc(stdin);
1197 while (YesNo != 'y' && YesNo != 'Y' && YesNo != 'n' && YesNo != 'N');
1199 if ((YesNo == 'y') || (YesNo == 'Y'))
1204 #endif /* AFS_SUN54_ENV */