Interdata732/usr/source/cmds/mkdir.c

Compare this file to the similar file:
Show the results in this format:

	/*	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);
}