1
0
Files
irix-657m-src/eoe/cmd/mkfs/mkfs.c
2022-09-29 17:59:04 +03:00

234 lines
4.7 KiB
C

#ident "$Revision: 1.7 $"
/*
* Front-end program for file-system specific mkfs's.
* Just figure out which program to execute and exec it.
* We know everything about efs and xfs mkfs arguments.
* Any other filesystem type can only be reached via -F or -t fstype
* as the first & second arguments.
* Since efs was there first, there's a strong preference for it.
* This means whenever we get anything we don't understand, we let efs
* mkfs complain about it.
*/
#include <sys/types.h>
#include <bstring.h>
#include <ctype.h>
#include <mntent.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <paths.h>
int chkexec(char *);
void doexec(char *, int, char **);
void fixpath(void);
main(int argc, char **argv)
{
int efs = 0;
int i;
char **nargv;
int xfs = 0;
static char efsname[] = MNTTYPE_EFS;
static char xfsname[] = MNTTYPE_XFS;
fixpath();
/*
* No arguments. Give them the xfs usage message.
*/
if (argc < 2)
doexec(xfsname, argc, argv);
/*
* Is the first thing in the argument list -F fstype or -t fstype?
*/
if ((strcmp(argv[1], "-F") == 0 || strcmp(argv[1], "-t") == 0) &&
argv[2] != NULL) {
/*
* Copy the remaining arguments & re-exec.
*/
nargv = malloc((argc - 1) * sizeof(*nargv));
bcopy(&argv[3], &nargv[1], (argc - 2) * sizeof(*nargv));
doexec(argv[2], argc - 2, nargv);
}
/*
* Must examine the argument list more closely, looking for
* distinguishing arguments.
* Any - arguments are always first, and most single arguments can
* be used to distinguish between efs and xfs.
*/
for (i = 1; argv[i] && argv[i][0] == '-'; i++) {
switch (argv[i][1]) {
/*
* EFS-only options
*/
case 'a':
efs++;
break;
/*
* XFS-only options
*/
case 'b':
case 'C':
case 'd':
case 'l':
case 'p':
xfs++;
break;
/*
* Can't tell which one this is.
*/
case 'q':
default:
break;
/*
* Can tell with a little work.
*/
case 'i':
case 'r':
/*
* Neither one, if the option letter is followed
* by something, or there is no next arg.
*/
if (argv[i][2] != '\0' || argv[i + 1] == NULL)
break;
/*
* If another - option or /filename it's efs.
*/
else if (argv[i + 1][0] == '-' || argv[i + 1][0] == '/')
efs++;
/*
* Option value containing = is xfs.
*/
else if (strchr(argv[i + 1], '=') != NULL)
xfs++;
else if (argv[i][1] == 'i' &&
strcmp(argv[i + 1], "align") == 0)
xfs++;
/*
* Something wrong, keep looking.
*/
else
break;
/*
* Can tell with a little work.
*/
case 'n':
/*
* Neither one, both -n options have a following arg.
*/
if (argv[i + 1] == NULL)
break;
/*
* xfs -n option has an embedded =
*/
else if (strchr(argv[i + 1], '=') != NULL)
xfs++;
/*
* efs -n option is a decimal number
*/
else if (isdigit(argv[i + 1][0]))
efs++;
/*
* Something wrong, keep looking.
*/
else
break;
}
if (efs)
doexec(efsname, argc, argv);
else if (xfs)
doexec(xfsname, argc, argv);
}
/*
* See if both mkfs's are there.
* If only one is present then we just run that one.
*/
if (!chkexec(efsname))
doexec(xfsname, argc, argv);
if (!chkexec(xfsname))
doexec(efsname, argc, argv);
/*
* i'th argument must be the special device name.
* If there are any further arguments, it must be efs.
*/
if (argc - i > 1)
doexec(efsname, argc, argv);
/*
* Else just assume it's xfs.
*/
doexec(xfsname, argc, argv);
}
/*
* Make sure that /sbin is in the
* path before execing user supplied mkfs program.
* We set the path to _PATH_ROOTPATH so no security problems can creep in.
*/
void
fixpath(void)
{
char *newpath;
static char prefix[] = "PATH=";
/*
* Allocate enough space for the path and the trailing null.
*/
newpath = malloc(strlen(prefix) + strlen(_PATH_ROOTPATH) + 1);
strcpy(newpath, prefix);
strcat(newpath, _PATH_ROOTPATH);
putenv(newpath);
}
/*
* Construct the name of the program, and exec it.
* If it fails complain and exit.
*/
void
doexec(char *fstype, int argc, char **argv)
{
char *name;
name = malloc(strlen(fstype) + 6);
sprintf(name, "mkfs_%s", fstype);
argv[0] = name;
execvp(name, argv);
perror(name);
exit(1);
}
/*
* Check to see if the executable is there.
*/
int
chkexec(char *fstype)
{
char *dir;
char *name;
int nstrlen;
char *p;
char *path;
char *pn;
int rval = 0;
nstrlen = strlen(fstype) + 5;
name = malloc(nstrlen + 1);
sprintf(name, "mkfs_%s", fstype);
p = path = strdup(_PATH_ROOTPATH);
while (dir = strtok(p, ":")) {
pn = malloc(strlen(dir) + nstrlen + 2);
sprintf(pn, "%s/%s", dir, name);
if (access(pn, EX_OK) == 0) {
free(pn);
rval = 1;
break;
}
free(pn);
p = NULL;
}
free(name);
free(path);
return rval;
}