The game rogue(6) has a potential buffer overflow allowing
[dragonfly.git] / release / sysinstall / floppy.c
1 /*
2  * The new sysinstall program.
3  *
4  * This is probably the last attempt in the `sysinstall' line, the next
5  * generation being slated to essentially a complete rewrite.
6  *
7  * $FreeBSD: src/release/sysinstall/floppy.c,v 1.34.2.2 2002/10/24 12:57:57 nyan Exp $
8  * $DragonFly: src/release/sysinstall/Attic/floppy.c,v 1.3 2003/08/08 04:18:36 dillon Exp $
9  *
10  * Copyright (c) 1995
11  *      Jordan Hubbard.  All rights reserved.
12  * Copyright (c) 1995
13  *      Gary J Palmer. All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer,
20  *    verbatim and that no modifications are made prior to this
21  *    point in the file.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  *
26  * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  */
39
40 /* These routines deal with getting things off of floppy media */
41
42 #include "sysinstall.h"
43 #include <sys/fcntl.h>
44 #include <sys/stat.h>
45 #include <sys/errno.h>
46 #include <sys/param.h>
47 #include <sys/wait.h>
48 #include <unistd.h>
49 #include <grp.h>
50
51 #define MSDOSFS
52 #include <sys/mount.h>
53 #include <msdosfs/msdosfsmount.h>
54 #undef MSDOSFS
55
56 #include <vfs/ufs/ufsmount.h>
57 static Boolean floppyMounted;
58
59 char *distWanted;
60 static char mountpoint[] = "/dist";
61
62 Boolean
63 mediaInitFloppy(Device *dev)
64 {
65     struct msdosfs_args dosargs;
66     struct ufs_args u_args;
67     char *mp;
68 #ifdef PC98
69     char fddev[24];
70 #endif
71
72     if (floppyMounted)
73         return TRUE;
74
75     mp = dev->private ? (char *)dev->private : mountpoint;
76     if (Mkdir(mp)) {
77         msgConfirm("Unable to make %s directory mountpoint for %s!", mp, dev->devname);
78         return FALSE;
79     }
80
81     msgDebug("Init floppy called for %s distribution.\n", distWanted ? distWanted : "some");
82
83     if (!variable_get(VAR_NONINTERACTIVE)) {
84         if (!distWanted)
85             msgConfirm("Please insert floppy in %s", dev->description);
86         else
87             msgConfirm("Please insert floppy containing %s in %s",
88                         distWanted, dev->description);
89     }
90
91     memset(&dosargs, 0, sizeof dosargs);
92 #ifdef PC98
93     dosargs.fspec = fddev;
94 #else
95     dosargs.fspec = dev->devname;
96 #endif
97     dosargs.uid = dosargs.gid = 0;
98     dosargs.mask = 0777;
99
100     memset(&u_args, 0, sizeof(u_args));
101 #ifdef PC98
102     u_args.fspec = fddev;
103 #else
104     u_args.fspec = dev->devname;
105 #endif
106
107 #ifdef PC98
108     snprintf(fddev, sizeof (fddev), "%s.1200", dev->devname);
109     if (mount("msdos", mp, MNT_RDONLY, (caddr_t)&dosargs) != -1)
110         goto success;
111     if (mount("ufs", mp, MNT_RDONLY, (caddr_t)&u_args) != -1)
112         goto success;
113
114     snprintf(fddev, sizeof (fddev), "%s.1232", dev->devname);
115     if (mount("msdos", mp, MNT_RDONLY, (caddr_t)&dosargs) != -1)
116         goto success;
117     if (mount("ufs", mp, MNT_RDONLY, (caddr_t)&u_args) != -1)
118         goto success;
119
120     snprintf(fddev, sizeof (fddev), "%s.1440", dev->devname);
121     if (mount("msdos", mp, MNT_RDONLY, (caddr_t)&dosargs) != -1)
122         goto success;
123     if (mount("ufs", mp, MNT_RDONLY, (caddr_t)&u_args) != -1)
124         goto success;
125 #else
126     if (mount("msdos", mp, MNT_RDONLY, (caddr_t)&dosargs) != -1)
127         goto success;
128     if (mount("ufs", mp, MNT_RDONLY, (caddr_t)&u_args) != -1)
129         goto success;
130 #endif /* PC98 */
131
132     msgConfirm("Error mounting floppy %s (%s) on %s : %s",
133                dev->name, dev->devname, mp, strerror(errno));
134     return FALSE;
135
136 success:
137     floppyMounted = TRUE;
138     distWanted = NULL;
139     return TRUE;
140 }
141
142 FILE *
143 mediaGetFloppy(Device *dev, char *file, Boolean probe)
144 {
145     char        buf[PATH_MAX], *mp;
146     FILE        *fp;
147     int         nretries = 5;
148
149     /*
150      * floppies don't use mediaGenericGet() because it's too expensive
151      * to speculatively open files on a floppy disk.  Make user get it
152      * right or give up with floppies.
153      */
154     mp = dev->private ? (char *)dev->private : mountpoint;
155     snprintf(buf, PATH_MAX, "%s/%s", mp, file);
156     if (!file_readable(buf)) {
157         if (probe)
158             return NULL;
159         else {
160             while (!file_readable(buf)) {
161                 if (!--nretries) {
162                     msgConfirm("GetFloppy: Failed to get %s after retries;\ngiving up.", buf);
163                     return NULL;
164                 }
165                 distWanted = buf;
166                 mediaShutdownFloppy(dev);
167                 if (!mediaInitFloppy(dev))
168                     return NULL;
169             }
170         }
171     }
172     fp = fopen(buf, "r");
173     return fp;
174 }
175
176 void
177 mediaShutdownFloppy(Device *dev)
178 {
179     if (floppyMounted) {
180         char *mp = dev->private ? (char *)dev->private : mountpoint;
181
182         if (unmount(mp, MNT_FORCE) != 0)
183             msgDebug("Umount of floppy on %s failed: %s (%d)\n", mp, strerror(errno), errno);
184         else {
185             floppyMounted = FALSE;
186             if (!variable_get(VAR_NONINTERACTIVE) && variable_cmp(SYSTEM_STATE, "fixit"))
187                 msgConfirm("You may remove the floppy from %s", dev->description);
188         }
189     }
190 }