|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 3740 (0xe9c)
Types: TextFile
Notes: UNIX file
Names: »mkdir.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/mkdir.c«
/*
* mkdir -- make directories
*/
#include <dir.h>
#include <sys/ino.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#define equal( s1, s2) (strcmp( s1, s2) == 0)
int interrupted;
char *getparent(),
*getchild(),
*concat(),
*malloc(),
*strcat(),
*strcpy(),
*strncpy();
/*
* main
* Interrupts are handled to prevent the formation of mangled directories.
*/
main(argc, argv)
register char **argv;
{
register int status = 0;
catch( SIGINT);
catch( SIGHUP);
signal( SIGQUIT, SIG_IGN);
if (*++argv == NULL)
{ fprintf(stderr, "Usage: mkdir dir ...\n");
exit(1);
}
else
while (*argv) {
if (mkdir( *argv++) < 0)
status = 1; /* error */
if (interrupted)
exit(1);
}
exit(status);
}
/*
* make a directory
* If the parent exists and is writeable, the directory and its "." and
* ".." links are created.
*/
mkdir( dir)
register char *dir;
{
register char *parent,
*child;
if ((int) (child = getchild( dir)) < 0) {
error("can't get child dir name %s", dir);
return(-1);
}
parent = getparent( dir);
if (equal( child, ".") || equal( child, "..")) {
error("%s not allowed", dir);
return(-1);
}
if (access( parent, 03))
switch (errno) {
case ENOENT:
error("parent dir %s doesn't exist", parent);
return(-1);
case EACCES:
error("no permission to mkdir in %s", parent);
return(-1);
default:
noway( dir);
}
if (mknod( dir, IFDIR|0777, 0))
switch (errno) {
case EEXIST:
error("%s already exists\n", dir);
return(-1);
case EPERM:
error("not the super-user");
return(-1);
default:
noway( dir);
}
if (link( dir, concat( dir, "/."))) {
linkerr( dir, ".");
return(-1);
}
if (link( parent, concat( dir, "/.."))) {
linkerr( dir, "..");
return(-1);
}
if (chown( dir, getuid( ), getgid( )) < 0)
return(-1);
}
/*
* return name of parent
*/
char *
getparent( dir)
char *dir;
{
register i;
register char *p;
static char *par;
int tmp;
if (par)
free( par);
i = strlen( dir);
par = malloc( i+1);
if (par == NULL) {
nomemory( );
return(-1);
}
strcpy( par, dir);
for (p=par+i; p>par; )
if (*--p != '/')
break;
for (++p; *--p!='/'; )
if (p == par) {
*p = '.';
break;
}
*++p = 0;
if (par[tmp = strlen(par)-1] == '/')
par[tmp] = 0; /* kill any ending slash */
return (par);
}
/*
* return rightmost component of pathname
*/
char *
getchild( dir)
register char *dir;
{
register char *p,
*q;
int i;
static char ch[DIRSIZ+1];
p = &dir[strlen( dir)];
do {
if (p == dir)
fatal( -1, "don't be silly");
} while (*--p == '/');
q = p;
while (q > dir)
if (*--q == '/') {
++q;
break;
}
i = p+1 - q;
if (i > DIRSIZ)
i = DIRSIZ;
return(strncpy( ch, q, i));
}
/*
* return concatenation of `s1' and `s2'
*/
char *
concat( s1, s2)
char *s1,
*s2;
{
static char *str;
if (str)
free( str);
str = malloc( strlen( s1)+strlen( s2)+1);
if (str == NULL) {
nomemory();
return(-1);
}
strcpy(str, s1);
return(strcat( str, s2));
}
/*
* recover from link failure
* In the event that "." or ".." cannot be created, remove all traces
* of the directory.
*/
linkerr( dir, name)
char *dir,
*name;
{
unlink( concat( dir, "/."));
unlink( concat( dir, "/.."));
unlink( dir);
error("link to '%s' failed", name);
return(-1);
}
nomemory()
{
error("out of memory");
return(-1);
}
noway(dir)
char *dir;
{
error("can't make %s", dir);
return(-1);
}
onintr( )
{
signal( SIGINT, SIG_IGN);
signal( SIGHUP, SIG_IGN);
++interrupted;
}
catch( sig)
{
if (signal( sig, SIG_IGN) == SIG_DFL)
signal( sig, onintr);
}
error(arg1)
char *arg1;
{
fprintf( stderr, "mkdir: %r\n", &arg1);
}
fatal(arg1)
char *arg1;
{
error(arg1);
exit(1);
}