Interdata_v6/usr/source/cmds/mkdir.c
/* mkdir dirname [dirname...] */
int uid;
int gid;
struct {
int dev;
int inode;
int modes;
char nlinks;
char uid;
char gid;
char size0;
int size;
int addr[8];
int actime[2];
int modtime[2];
} statbuff;
main(argc, argv)
char **argv;
{
uid = getuid() & 0377;
gid = getgid() & 0377;
while (--argc)
make(*++argv);
}
make(name)
char *name;
{
char buff[100];
register char *pdir, *p, *q;
register m;
/*
* Copy filename to buffer -- leave p pointing at last char
*/
q = name;
for (p=buff; *p = *q++; p++)
if (p >= &buff[sizeof buff - 4]) {
printf("%.64s... : name too long\n", name);
return;
}
/*
* Check for write permission in parent directory
*/
pdir = parent(name);
if (stat(pdir, &statbuff) < 0) {
printf("Can't find %s\n", pdir);
return;
}
if (uid) {
m = statbuff.modes;
if (uid == statbuff.uid)
m =>> 6;
else if (gid == statbuff.gid)
m =>> 3;
if ((m & 02) == 0) {
printf("No write permission in %s\n", pdir);
return;
}
}
/*
* Make directory node, and change owner to caller's userid
*/
if (mknod(name, 0140777, 0) < 0) {
perror(name);
return;
}
if (chown(name, (gid<<8) + uid) < 0)
perror(name);
/*
* Link standard entries '.' and '..'
*/
p[0] = '/';
p[2] = p[1] = '.';
p[3] = '\0';
if (link(pdir, buff) < 0) {
printf("Can't make entry '..'\n");
return;
}
p[2] = '\0';
if (link(name, buff) < 0) {
printf("Can't make entry '.'\n");
return;
}
}
/*
* Given a filename, construct the name of its parent directory
*/
parent(fname)
char *fname;
{
static char pbuff[100];
register char *f, *p, *slash;
register c;
/*
* Copy filename to buffer, remembering position of last '/'
*/
slash = 0;
f = fname;
for (p = pbuff; c = *f++; p++) {
if (c == '/')
slash = p;
*p = c;
}
/*
* no slash found - parent is "."
* otherwise - parent is "xxx/."
*/
if (slash == 0)
return(".");
slash[1] = '.';
slash[2] = '\0';
return(pbuff);
}