]>
git.ipfire.org Git - people/ummeegge/ipfire-2.x.git/blob - src/nash/nash.c
4 * Simple code to load modules, mount root, and get things going. Uses
5 * dietlibc to keep things small.
7 * Erik Troan (ewt@redhat.com)
9 * Copyright 2002 Red Hat Software
11 * This software may be freely redistributed under the terms of the GNU
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* We internalize losetup, mount, raidautorun, and echo commands. Other
21 commands are run from the filesystem. Comments and blank lines work as
22 well, argument parsing is screwy. */
33 #include <sys/ioctl.h>
34 #include <sys/mount.h>
35 #include <sys/socket.h>
38 #include <sys/types.h>
42 #include <sys/ioctl.h>
43 #include <sys/reboot.h>
46 #include <asm/unistd.h>
48 #include "mount_by_label.h"
50 /* Need to tell loop.h what the actual dev_t type is. */
52 #if defined(__alpha) || (defined(__sparc__) && defined(__arch64__))
53 #define dev_t unsigned int
55 #define dev_t unsigned short
57 #include <linux/loop.h>
61 #define syslog klogctl
63 #include <linux/cdrom.h>
65 #include <linux/raid/md_u.h>
68 #define RAID_AUTORUN _IO (MD_MAJOR, 0x14)
76 static inline _syscall2(int,pivot_root
,const char *,one
,const char *,two
)
79 #define MAX(a, b) ((a) > (b) ? a : b)
81 int testing
= 0, quiet
= 0;
83 #define PATH "/usr/bin:/bin:/sbin:/usr/sbin"
90 int smartmknod(char * device
, mode_t mode
, dev_t dev
) {
100 if (access(buf
, F_OK
) && errno
== ENOENT
)
108 return mknod(device
, mode
, dev
);
111 char * getArg(char * cmd
, char * end
, char ** arg
) {
114 if (cmd
>= end
) return NULL
;
116 while (isspace(*cmd
) && cmd
< end
) cmd
++;
117 if (cmd
>= end
) return NULL
;
121 else if (*cmd
== '\'')
127 /* This doesn't support \ escapes */
128 while (cmd
< end
&& *cmd
!= quote
) cmd
++;
131 printf("error: quote mismatch for %s\n", *arg
);
139 while (!isspace(*cmd
) && cmd
< end
) cmd
++;
145 while (isspace(*cmd
)) cmd
++;
150 int mountCommand(char * cmd
, char * end
) {
151 char * fsType
= NULL
;
155 char * options
= NULL
;
157 int mustRemoveDir
= 0;
159 int flags
= MS_MGC_VAL
;
162 cmd
= getArg(cmd
, end
, &device
);
164 printf("usage: mount [--ro] [-o <opts>] -t <type> <device> <mntpoint>\n");
168 while (cmd
&& *device
== '-') {
169 if (!strcmp(device
, "--ro")) {
171 } else if (!strcmp(device
, "-o")) {
172 cmd
= getArg(cmd
, end
, &options
);
174 printf("mount: -o requires arguments\n");
177 } else if (!strcmp(device
, "-t")) {
178 if (!(cmd
= getArg(cmd
, end
, &fsType
))) {
179 printf("mount: missing filesystem type\n");
184 cmd
= getArg(cmd
, end
, &device
);
188 printf("mount: missing device\n");
192 if (!(cmd
= getArg(cmd
, end
, &mntPoint
))) {
193 printf("mount: missing mount point\n");
198 printf("mount: filesystem type expected\n");
203 printf("mount: unexpected arguments\n");
207 /* need to deal with options */
210 char * start
= options
;
212 newOpts
= alloca(strlen(options
) + 1);
216 end
= strchr(start
, ',');
218 end
= start
+ strlen(start
);
224 if (!strcmp(start
, "ro"))
226 else if (!strcmp(start
, "rw"))
228 else if (!strcmp(start
, "nosuid"))
230 else if (!strcmp(start
, "suid"))
232 else if (!strcmp(start
, "nodev"))
234 else if (!strcmp(start
, "dev"))
236 else if (!strcmp(start
, "noexec"))
238 else if (!strcmp(start
, "exec"))
240 else if (!strcmp(start
, "sync"))
241 flags
|= MS_SYNCHRONOUS
;
242 else if (!strcmp(start
, "async"))
243 flags
&= ~MS_SYNCHRONOUS
;
244 else if (!strcmp(start
, "nodiratime"))
245 flags
|= MS_NODIRATIME
;
246 else if (!strcmp(start
, "diratime"))
247 flags
&= ~MS_NODIRATIME
;
248 else if (!strcmp(start
, "noatime"))
250 else if (!strcmp(start
, "atime"))
251 flags
&= ~MS_NOATIME
;
252 else if (!strcmp(start
, "remount"))
254 else if (!strcmp(start
, "defaults"))
258 strcat(newOpts
, ",");
259 strcat(newOpts
, start
);
268 if (!strncmp("LABEL=", device
, 6)) {
274 devName
= get_spec_by_volume_label(device
+ 6, &major
, &minor
);
278 if (access(device
, F_OK
)) {
285 deviceDir
= alloca(strlen(device
) + 1);
286 strcpy(deviceDir
, device
);
287 ptr
= deviceDir
+ (strlen(device
) - 1);
290 if (mkdir(deviceDir
, 0644)) {
291 printf("mkdir: cannot create directory %s\n", deviceDir
);
296 if (smartmknod(device
, S_IFBLK
| 0600, makedev(major
, minor
))) {
297 printf("mount: cannot create device %s (%d,%d)\n",
298 device
, major
, minor
);
307 printf("mount %s%s%s-t '%s' '%s' '%s' (%s%s%s%s%s%s%s)\n",
308 options
? "-o '" : "",
309 options
? options
: "",
310 options
? "\' " : "",
311 fsType
, device
, mntPoint
,
312 (flags
& MS_RDONLY
) ? "ro " : "",
313 (flags
& MS_NOSUID
) ? "nosuid " : "",
314 (flags
& MS_NODEV
) ? "nodev " : "",
315 (flags
& MS_NOEXEC
) ? "noexec " : "",
316 (flags
& MS_SYNCHRONOUS
) ? "sync " : "",
317 (flags
& MS_REMOUNT
) ? "remount " : "",
318 (flags
& MS_NOATIME
) ? "noatime " : ""
321 if (mount(device
, mntPoint
, fsType
, flags
, options
)) {
322 printf("mount: error %d mounting %s\n", errno
, fsType
);
327 if (mustRemove
) unlink(device
);
328 if (mustRemoveDir
) rmdir(deviceDir
);
333 int otherCommand(char * bin
, char * cmd
, char * end
, int doFork
) {
339 const static char * sysPath
= PATH
;
340 const char * pathStart
;
341 const char * pathEnd
;
342 char * stdoutFile
= NULL
;
347 if (!strchr(bin
, '/')) {
350 pathEnd
= strchr(pathStart
, ':');
352 if (!pathEnd
) pathEnd
= pathStart
+ strlen(pathStart
);
354 strncpy(fullPath
, pathStart
, pathEnd
- pathStart
);
355 fullPath
[pathEnd
- pathStart
] = '/';
356 strcpy(fullPath
+ (pathEnd
- pathStart
+ 1), bin
);
359 if (*pathStart
) pathStart
++;
361 if (!access(fullPath
, X_OK
)) {
370 while (cmd
&& cmd
< end
) {
372 cmd
= getArg(cmd
, end
, nextArg
);
378 /* if the next-to-last arg is a >, redirect the output properly */
379 if (((nextArg
- args
) >= 2) && !strcmp(*(nextArg
- 2), ">")) {
380 stdoutFile
= *(nextArg
- 1);
381 *(nextArg
- 2) = NULL
;
383 stdoutFd
= open(stdoutFile
, O_CREAT
| O_RDWR
| O_TRUNC
, 0600);
385 printf("nash: failed to open %s: %d\n", stdoutFile
, errno
);
394 printf(" '%s'", *nextArg
++);
396 printf(" (> %s)", stdoutFile
);
399 if (!doFork
|| !(pid
= fork())) {
402 execve(args
[0], args
, env
);
403 printf("ERROR: failed in exec of %s\n", args
[0]);
409 wait4(-1, &status
, 0, NULL
);
410 if (!WIFEXITED(status
) || WEXITSTATUS(status
)) {
411 printf("ERROR: %s exited abnormally!\n", args
[0]);
419 int execCommand(char * cmd
, char * end
) {
422 if (!(cmd
= getArg(cmd
, end
, &bin
))) {
423 printf("exec: argument expected\n");
427 return otherCommand(bin
, cmd
, end
, 0);
430 int losetupCommand(char * cmd
, char * end
) {
434 struct loop_info loopInfo
;
437 if (!(cmd
= getArg(cmd
, end
, &device
))) {
438 printf("losetup: missing device\n");
442 if (!(cmd
= getArg(cmd
, end
, &file
))) {
443 printf("losetup: missing file\n");
448 printf("losetup: unexpected arguments\n");
453 printf("losetup '%s' '%s'\n", device
, file
);
455 dev
= open(device
, O_RDWR
, 0);
457 printf("losetup: failed to open %s: %d\n", device
, errno
);
461 fd
= open(file
, O_RDWR
, 0);
463 printf("losetup: failed to open %s: %d\n", file
, errno
);
468 if (ioctl(dev
, LOOP_SET_FD
, (long) fd
)) {
469 printf("losetup: LOOP_SET_FD failed: %d\n", errno
);
477 memset(&loopInfo
, 0, sizeof(loopInfo
));
478 strcpy(loopInfo
.lo_name
, file
);
480 if (ioctl(dev
, LOOP_SET_STATUS
, &loopInfo
))
481 printf("losetup: LOOP_SET_STATUS failed: %d\n", errno
);
489 int raidautorunCommand(char * cmd
, char * end
) {
493 if (!(cmd
= getArg(cmd
, end
, &device
))) {
494 printf("raidautorun: raid device expected as first argument\n");
499 printf("raidautorun: unexpected arguments\n");
503 fd
= open(device
, O_RDWR
, 0);
505 printf("raidautorun: failed to open %s: %d\n", device
, errno
);
509 if (ioctl(fd
, RAID_AUTORUN
, 0)) {
510 printf("raidautorun: RAID_AUTORUN failed: %d\n", errno
);
519 static int my_pivot_root(char * one
, char * two
) {
521 return pivot_root(one
, two
);
523 return syscall(__NR_pivot_root
, one
, two
);
527 int pivotrootCommand(char * cmd
, char * end
) {
531 if (!(cmd
= getArg(cmd
, end
, &new))) {
532 printf("pivotroot: new root mount point expected\n");
536 if (!(cmd
= getArg(cmd
, end
, &old
))) {
537 printf("pivotroot: old root mount point expected\n");
542 printf("pivotroot: unexpected arguments\n");
546 if (my_pivot_root(new, old
)) {
547 printf("pivotroot: pivot_root(%s,%s) failed: %d\n", new, old
, errno
);
554 int echoCommand(char * cmd
, char * end
) {
556 char ** nextArg
= args
;
561 if (testing
&& !quiet
) {
566 while ((cmd
= getArg(cmd
, end
, nextArg
)))
569 if ((nextArg
- args
>= 2) && !strcmp(*(nextArg
- 2), ">")) {
570 outFd
= open(*(nextArg
- 1), O_RDWR
| O_CREAT
| O_TRUNC
, 0644);
572 printf("echo: cannot open %s for write: %d\n",
573 *(nextArg
- 1), errno
);
580 for (i
= 0; i
< num
;i
++) {
582 write(outFd
, " ", 1);
583 write(outFd
, args
[i
], strlen(args
[i
]));
586 write(outFd
, "\n", 1);
588 if (outFd
!= 1) close(outFd
);
593 int umountCommand(char * cmd
, char * end
) {
596 if (!(cmd
= getArg(cmd
, end
, &path
))) {
597 printf("umount: path expected\n");
602 printf("umount: unexpected arguments\n");
607 printf("umount %s failed: %d\n", path
, errno
);
614 int mkrootdevCommand(char * cmd
, char * end
) {
616 char * start
, * chptr
;
617 unsigned int devNum
= 0;
623 if (!(cmd
= getArg(cmd
, end
, &path
))) {
624 printf("mkrootdev: path expected\n");
629 printf("mkrootdev: unexpected arguments\n");
633 fd
= open("/proc/cmdline", O_RDONLY
, 0);
635 printf("mkrootdev: failed to open /proc/cmdline: %d\n", errno
);
639 i
= read(fd
, buf
, sizeof(buf
));
641 printf("mkrootdev: failed to read /proc/cmdline: %d\n", errno
);
650 while (*start
&& isspace(*start
)) start
++;
651 while (*start
&& strncmp(start
, "root=", 5)) {
652 while (*start
&& !isspace(*start
)) start
++;
653 while (*start
&& isspace(*start
)) start
++;
658 while (*chptr
&& !isspace(*chptr
)) chptr
++;
661 if (!strncmp(start
, "LABEL=", 6)) {
662 if (get_spec_by_volume_label(start
+ 6, &major
, &minor
)) {
663 if (smartmknod(path
, S_IFBLK
| 0600, makedev(major
, minor
))) {
664 printf("mount: cannot create device %s (%d,%d)\n",
672 printf("mkrootdev: label %s not found\n", start
+ 6);
677 fd
= open("/proc/sys/kernel/real-root-dev", O_RDONLY
, 0);
679 printf("mkrootdev: failed to open /proc/sys/kernel/real-root-dev: %d\n", errno
);
683 i
= read(fd
, buf
, sizeof(buf
));
685 printf("mkrootdev: failed to read real-root-dev: %d\n", errno
);
695 printf("mkrootdev: bad device %s\n", buf
);
699 if (smartmknod(path
, S_IFBLK
| 0700, devNum
)) {
700 printf("mkrootdev: mknod failed: %d\n", errno
);
707 int mkdirCommand(char * cmd
, char * end
) {
709 int ignoreExists
= 0;
711 cmd
= getArg(cmd
, end
, &dir
);
713 if (cmd
&& !strcmp(dir
, "-p")) {
715 cmd
= getArg(cmd
, end
, &dir
);
719 printf("mkdir: directory expected\n");
723 if (mkdir(dir
, 0755)) {
724 if (!ignoreExists
&& errno
== EEXIST
) {
725 printf("mkdir: failed to create %s: %d\n", dir
, errno
);
733 int accessCommand(char * cmd
, char * end
) {
738 cmd
= getArg(cmd
, end
, &permStr
);
739 if (cmd
) cmd
= getArg(cmd
, end
, &file
);
741 if (!cmd
|| *permStr
!= '-') {
742 printf("usage: access -[perm] file\n");
749 case 'r': perms
|= R_OK
; break;
750 case 'w': perms
|= W_OK
; break;
751 case 'x': perms
|= X_OK
; break;
752 case 'f': perms
|= F_OK
; break;
754 printf("perms must be -[r][w][x][f]\n");
761 if (access(file
, perms
))
767 int sleepCommand(char * cmd
, char * end
) {
771 if (!(cmd
= getArg(cmd
, end
, &delaystr
))) {
772 printf("sleep: delay expected\n");
776 delay
= atoi(delaystr
);
782 int readlinkCommand(char * cmd
, char * end
) {
784 char * buf
, * respath
, * fullpath
;
787 if (!(cmd
= getArg(cmd
, end
, &path
))) {
788 printf("readlink: file expected\n");
792 if (lstat(path
, &sb
) == -1) {
793 fprintf(stderr
, "unable to stat %s: %d\n", path
, errno
);
797 if (!S_ISLNK(sb
.st_mode
)) {
798 printf("%s\n", path
);
803 if (readlink(path
, buf
, 512) == -1) {
804 fprintf(stderr
, "error readlink %s: %d\n", path
, errno
);
808 /* symlink is absolute */
814 /* nope, need to handle the relative symlink case too */
815 respath
= strrchr(path
, '/');
820 fullpath
= malloc(512);
821 /* and normalize it */
822 snprintf(fullpath
, 512, "%s/%s", path
, buf
);
823 respath
= malloc(PATH_MAX
);
824 if (!(respath
= realpath(fullpath
, respath
))) {
825 fprintf(stderr
, "error realpath %s: %d\n", fullpath
, errno
);
829 printf("%s\n", respath
);
833 int doFind(char * dirName
, char * name
) {
837 char * strBuf
= alloca(strlen(dirName
) + 1024);
839 if (!(dir
= opendir(dirName
))) {
840 fprintf(stderr
, "error opening %s: %d\n", dirName
, errno
);
845 while ((d
= readdir(dir
))) {
848 strcpy(strBuf
, dirName
);
850 strcat(strBuf
, d
->d_name
);
852 if (!strcmp(d
->d_name
, name
))
853 printf("%s\n", strBuf
);
855 if (!strcmp(d
->d_name
, ".") || !strcmp(d
->d_name
, "..")) {
860 if (lstat(strBuf
, &sb
)) {
861 fprintf(stderr
, "failed to stat %s: %d\n", strBuf
, errno
);
866 if (S_ISDIR(sb
.st_mode
))
867 doFind(strBuf
, name
);
872 printf("error reading from %s: %d\n", dirName
, errno
);
881 int findCommand(char * cmd
, char * end
) {
885 cmd
= getArg(cmd
, end
, &dir
);
886 if (cmd
) cmd
= getArg(cmd
, end
, &name
);
887 if (cmd
&& strcmp(name
, "-name")) {
888 printf("usage: find [path] -name [file]\n");
892 if (cmd
) cmd
= getArg(cmd
, end
, &name
);
894 printf("usage: find [path] -name [file]\n");
898 return doFind(dir
, name
);
901 int findlodevCommand(char * cmd
, char * end
) {
905 struct loop_info loopInfo
;
906 char separator
[2] = "";
909 printf("usage: findlodev\n");
913 if (!access("/dev/.devfsd", X_OK
))
914 strcpy(separator
, "/");
916 for (devNum
= 0; devNum
< 256; devNum
++) {
917 sprintf(devName
, "/dev/loop%s%d", separator
, devNum
);
918 if ((fd
= open(devName
, O_RDONLY
)) < 0) return 0;
920 if (ioctl(fd
, LOOP_GET_STATUS
, &loopInfo
)) {
922 printf("%s\n", devName
);
932 int mknodCommand(char * cmd
, char * end
) {
934 char * majorStr
, * minorStr
;
940 cmd
= getArg(cmd
, end
, &path
);
941 cmd
= getArg(cmd
, end
, &type
);
942 cmd
= getArg(cmd
, end
, &majorStr
);
943 cmd
= getArg(cmd
, end
, &minorStr
);
945 printf("mknod: usage mknod <path> [c|b] <major> <minor>\n");
949 if (!strcmp(type
, "b")) {
951 } else if (!strcmp(type
, "c")) {
954 printf("mknod: invalid type\n");
958 major
= strtol(majorStr
, &chptr
, 10);
960 printf("invalid major number\n");
964 minor
= strtol(minorStr
, &chptr
, 10);
966 printf("invalid minor number\n");
970 if (smartmknod(path
, mode
| 0600, makedev(major
, minor
))) {
971 printf("mknod: failed to create %s: %d\n", path
, errno
);
978 int mkdevicesCommand(char * cmd
, char * end
) {
982 char * start
, * chptr
;
988 if (!(cmd
= getArg(cmd
, end
, &prefix
))) {
989 printf("mkdevices: path expected\n");
994 printf("mkdevices: unexpected arguments\n");
998 if ((fd
= open("/proc/partitions", O_RDONLY
)) < 0) {
999 printf("mkrootdev: failed to open /proc/partitions: %d\n", errno
);
1003 i
= read(fd
, buf
, sizeof(buf
));
1006 printf("failed to read /proc/partitions: %d\n", errno
);
1012 start
= strchr(buf
, '\n');
1015 start
= strchr(buf
, '\n');
1017 if (!start
) return 1;
1021 while (*start
&& isspace(*start
)) start
++;
1022 major
= strtol(start
, &chptr
, 10);
1024 if (start
!= chptr
) {
1026 while (*start
&& isspace(*start
)) start
++;
1027 minor
= strtol(start
, &chptr
, 10);
1029 if (start
!= chptr
) {
1031 while (*start
&& isspace(*start
)) start
++;
1032 while (*start
&& !isspace(*start
)) start
++;
1033 while (*start
&& isspace(*start
)) start
++;
1038 while (!isspace(*chptr
)) chptr
++;
1043 printf("% 3d % 3d %s\n", major
, minor
, start
);
1045 char * ptr
, * deviceDir
;
1048 sprintf(devName
, "%s/%s", prefix
, start
);
1057 deviceDir
= alloca(strlen(devName
) + 1);
1058 strcpy(deviceDir
, devName
);
1059 ptr
= deviceDir
+ (strlen(devName
) - 1);
1062 if (access(deviceDir
, X_OK
) && mkdir(deviceDir
, 0644)) {
1063 printf("mkdir: cannot create directory %s: %d\n", deviceDir
, errno
);
1066 if (smartmknod(devName
, S_IFBLK
| 0600,
1067 makedev(major
, minor
))) {
1068 printf("failed to create %s\n", devName
);
1079 start
= strchr(start
, '\n');
1080 if (!*start
) return 1;
1087 int runStartup(int fd
) {
1088 char contents
[32768];
1090 char * start
, * end
;
1094 i
= read(fd
, contents
, sizeof(contents
) - 1);
1095 if (i
== (sizeof(contents
) - 1)) {
1096 printf("Failed to read /startup.rc -- file too large.\n");
1104 while (isspace(*start
) && *start
&& (*start
!= '\n')) start
++;
1107 while (*start
&& (*start
!= '\n')) start
++;
1109 if (*start
== '\n') {
1115 printf("(last line in /startup.rc is empty)\n");
1119 /* start points to the beginning of the command */
1121 while (*end
&& (*end
!= '\n')) end
++;
1123 printf("(last line in /startup.rc missing \\n -- skipping)\n");
1128 /* end points to the \n at the end of the command */
1131 while (chptr
< end
&& !isspace(*chptr
)) chptr
++;
1133 if (!strncmp(start
, "mount", MAX(5, chptr
- start
)))
1134 rc
= mountCommand(chptr
, end
);
1135 else if (!strncmp(start
, "losetup", MAX(7, chptr
- start
)))
1136 rc
= losetupCommand(chptr
, end
);
1137 else if (!strncmp(start
, "echo", MAX(4, chptr
- start
)))
1138 rc
= echoCommand(chptr
, end
);
1139 else if (!strncmp(start
, "raidautorun", MAX(11, chptr
- start
)))
1140 rc
= raidautorunCommand(chptr
, end
);
1141 else if (!strncmp(start
, "pivot_root", MAX(10, chptr
- start
)))
1142 rc
= pivotrootCommand(chptr
, end
);
1143 else if (!strncmp(start
, "mkrootdev", MAX(9, chptr
- start
)))
1144 rc
= mkrootdevCommand(chptr
, end
);
1145 else if (!strncmp(start
, "umount", MAX(6, chptr
- start
)))
1146 rc
= umountCommand(chptr
, end
);
1147 else if (!strncmp(start
, "exec", MAX(4, chptr
- start
)))
1148 rc
= execCommand(chptr
, end
);
1149 else if (!strncmp(start
, "mkdir", MAX(5, chptr
- start
)))
1150 rc
= mkdirCommand(chptr
, end
);
1151 else if (!strncmp(start
, "access", MAX(6, chptr
- start
)))
1152 rc
= accessCommand(chptr
, end
);
1153 else if (!strncmp(start
, "find", MAX(4, chptr
- start
)))
1154 rc
= findCommand(chptr
, end
);
1155 else if (!strncmp(start
, "findlodev", MAX(7, chptr
- start
)))
1156 rc
= findlodevCommand(chptr
, end
);
1157 else if (!strncmp(start
, "showlabels", MAX(10, chptr
-start
)))
1158 rc
= display_uuid_cache();
1159 else if (!strncmp(start
, "mkdevices", MAX(9, chptr
-start
)))
1160 rc
= mkdevicesCommand(chptr
, end
);
1161 else if (!strncmp(start
, "sleep", MAX(5, chptr
-start
)))
1162 rc
= sleepCommand(chptr
, end
);
1163 else if (!strncmp(start
, "mknod", MAX(5, chptr
-start
)))
1164 rc
= mknodCommand(chptr
, end
);
1165 else if (!strncmp(start
, "readlink", MAX(8, chptr
-start
)))
1166 rc
= readlinkCommand(chptr
, end
);
1169 rc
= otherCommand(start
, chptr
+ 1, end
, 1);
1178 int main(int argc
, char **argv
) {
1184 name
= strrchr(argv
[0], '/');
1190 if (!strcmp(name
, "modprobe"))
1193 testing
= (getppid() != 0) && (getppid() != 1);
1196 while (argc
&& **argv
== '-') {
1197 if (!strcmp(*argv
, "--force")) {
1201 } else if (!strcmp(*argv
, "--quiet")) {
1205 printf("unknown argument %s\n", *argv
);
1210 if (force
&& !quiet
)
1211 printf("(forcing normal run)\n");
1213 if (testing
&& !quiet
)
1214 printf("(running in test mode).\n");
1216 if (!quiet
) printf("Red Hat nash version %s starting\n", VERSION
);
1219 fd
= open(*argv
, O_RDONLY
, 0);
1221 printf("nash: cannot open %s: %d\n", *argv
, errno
);
1226 rc
= runStartup(fd
);