コード例 #1
0
ファイル: pseudo.c プロジェクト: rampageX/firmware-mod-kit
int read_pseudo_def(struct pseudo **pseudo, char *def)
{
	int n, bytes;
	unsigned int major = 0, minor = 0, mode;
	char filename[2048], type, suid[100], sgid[100], *ptr;
	long long uid, gid;
	struct pseudo_dev *dev;

	n = sscanf(def, "%s %c %o %s %s %n", filename, &type, &mode, suid,
			sgid, &bytes);

	if(n < 5) {
		ERROR("Not enough or invalid arguments in pseudo file "
			"definition\n");
		goto error;
	}

	switch(type) {
	case 'b':
	case 'c':
		n = sscanf(def + bytes,  "%u %u", &major, &minor);

		if(n < 2) {
			ERROR("Not enough or invalid arguments in pseudo file "
				"definition\n");
			goto error;
		}	
		
		if(major > 0xfff) {
			ERROR("Major %d out of range\n", major);
			goto error;
		}

		if(minor > 0xfffff) {
			ERROR("Minor %d out of range\n", minor);
			goto error;
		}

	case 'f':
		if(def[bytes] == '\0') {
			ERROR("Not enough arguments in pseudo file "
				"definition\n");
			goto error;
		}	
		break;
	case 'd':
	case 'm':
		break;
	default:
		ERROR("Unsupported type %c\n", type);
		goto error;
	}


	if(mode > 07777) {
		ERROR("Mode %o out of range\n", mode);
		goto error;
	}

	uid = strtoll(suid, &ptr, 10);
	if(*ptr == '\0') {
		if(uid < 0 || uid > ((1LL << 32) - 1)) {
			ERROR("Uid %s out of range\n", suid);
			goto error;
		}
	} else {
		struct passwd *pwuid = getpwnam(suid);
		if(pwuid)
			uid = pwuid->pw_uid;
		else {
			ERROR("Uid %s invalid uid or unknown user\n", suid);
			goto error;
		}
	}
		
	gid = strtoll(sgid, &ptr, 10);
	if(*ptr == '\0') {
		if(gid < 0 || gid > ((1LL << 32) - 1)) {
			ERROR("Gid %s out of range\n", sgid);
			goto error;
		}
	} else {
		struct group *grgid = getgrnam(sgid);
		if(grgid)
			gid = grgid->gr_gid;
		else {
			ERROR("Gid %s invalid uid or unknown user\n", sgid);
			goto error;
		}
	}

	switch(type) {
	case 'b':
		mode |= S_IFBLK;
		break;
	case 'c':
		mode |= S_IFCHR;
		break;
	case 'd':
		mode |= S_IFDIR;
		break;
	case 'f':
		mode |= S_IFREG;
		break;
	}

	dev = malloc(sizeof(struct pseudo_dev));
	if(dev == NULL)
		BAD_ERROR("Failed to create pseudo_dev\n");

	dev->type = type;
	dev->mode = mode;
	dev->uid = uid;
	dev->gid = gid;
	dev->major = major;
	dev->minor = minor;

	if(type == 'f') {
		int res;

		printf("Executing dynamic pseudo file\n");
		printf("\t\"%s\"\n", def);
		res = exec_file(def + bytes, dev);
		if(res == -1) {
			ERROR("Failed to execute dynamic pseudo file definition"
				" \"%s\"\n", def);
			return FALSE;
		}
		add_pseudo_file(dev);
	}

	*pseudo = add_pseudo(*pseudo, dev, filename, filename);

	return TRUE;

error:
	ERROR("Bad pseudo file definition \"%s\"\n", def);
	return FALSE;
}
コード例 #2
0
ファイル: pseudo.c プロジェクト: rampageX/firmware-mod-kit
/*
 * Add pseudo device target to the set of pseudo devices.  Pseudo_dev
 * describes the pseudo device attributes.
 */
struct pseudo *add_pseudo(struct pseudo *pseudo, struct pseudo_dev *pseudo_dev,
	char *target, char *alltarget)
{
	char targname[1024];
	int i;

	target = get_component(target, targname);

	if(pseudo == NULL) {
		if((pseudo = malloc(sizeof(struct pseudo))) == NULL)
			BAD_ERROR("failed to allocate pseudo file\n");

		pseudo->names = 0;
		pseudo->count = 0;
		pseudo->name = NULL;
	}

	for(i = 0; i < pseudo->names; i++)
		if(strcmp(pseudo->name[i].name, targname) == 0)
			break;

	if(i == pseudo->names) {
		/* allocate new name entry */
		pseudo->names ++;
		pseudo->name = realloc(pseudo->name, (i + 1) *
			sizeof(struct pseudo_entry));
		if(pseudo->name == NULL)
			BAD_ERROR("failed to allocate pseudo file\n");
		pseudo->name[i].name = strdup(targname);

		if(target[0] == '\0') {
			/* at leaf pathname component */
			pseudo->name[i].pseudo = NULL;
			pseudo->name[i].pathname = strdup(alltarget);
			pseudo->name[i].dev = pseudo_dev;
		} else {
			/* recurse adding child components */
			pseudo->name[i].dev = NULL;
			pseudo->name[i].pseudo = add_pseudo(NULL, pseudo_dev,
				target, alltarget);
		}
	} else {
		/* existing matching entry */
		if(pseudo->name[i].pseudo == NULL) {
			/* No sub-directory which means this is the leaf
			 * component of a pre-existing pseudo file.
			 */
			if(target[0] != '\0') {
				/* entry must exist as a 'd' type pseudo file */
				if(pseudo->name[i].dev->type == 'd')
					/* recurse adding child components */
					pseudo->name[i].pseudo =
						add_pseudo(NULL, pseudo_dev,
						target, alltarget);
				else
					ERROR("%s already exists as a non "
						"directory.  Ignoring %s!\n",
						 targname, alltarget);
			} else if(memcmp(pseudo_dev, pseudo->name[i].dev,
					sizeof(struct pseudo_dev)) != 0)
				ERROR("%s already exists as a different pseudo "
					"definition.  Ignoring!\n", alltarget);
			else ERROR("%s already exists as an identical "
					"pseudo definition!\n", alltarget);
		} else {
			/* sub-directory exists which means this can only be a
			 * 'd' type pseudo file */
			if(target[0] == '\0') {
				if(pseudo->name[i].dev == NULL &&
						pseudo_dev->type == 'd') {
					pseudo->name[i].pathname =
						strdup(alltarget);
					pseudo->name[i].dev = pseudo_dev;
				} else
					ERROR("%s already exists as a "
						"directory.  Ignoring %s!\n",
						targname, alltarget);
			} else
				/* recurse adding child components */
				add_pseudo(pseudo->name[i].pseudo, pseudo_dev,
					target, alltarget);
		}
	}

	return pseudo;
}
コード例 #3
0
ファイル: pseudo.c プロジェクト: Distrotech/squashfs
int read_pseudo_def(char *def)
{
	int n, bytes;
	unsigned int major = 0, minor = 0, mode;
	char type, *ptr;
	char suid[100], sgid[100]; /* overflow safe */
	char *filename, *name;
	char *orig_def = def;
	long long uid, gid;
	struct pseudo_dev *dev;

	/*
	 * Scan for filename, don't use sscanf() and "%s" because
	 * that can't handle filenames with spaces
	 */
	filename = malloc(strlen(def) + 1);
	if(filename == NULL)
		MEM_ERROR();

	for(name = filename; !isspace(*def) && *def != '\0';) {
		if(*def == '\\') {
			def ++;
			if (*def == '\0')
				break;
		}
		*name ++ = *def ++;
	}
	*name = '\0';

	if(*filename == '\0') {
		ERROR("Not enough or invalid arguments in pseudo file "
			"definition \"%s\"\n", orig_def);
		goto error;
	}

	n = sscanf(def, " %c %o %99s %99s %n", &type, &mode, suid, sgid,
		&bytes);
	def += bytes;

	if(n < 4) {
		ERROR("Not enough or invalid arguments in pseudo file "
			"definition \"%s\"\n", orig_def);
		switch(n) {
		case -1:
			/* FALLTHROUGH */
		case 0:
			ERROR("Read filename, but failed to read or match "
				"type\n");
			break;
		case 1:
			ERROR("Read filename and type, but failed to read or "
				"match octal mode\n");
			break;
		case 2:
			ERROR("Read filename, type and mode, but failed to "
				"read or match uid\n");
			break;
		default:
			ERROR("Read filename, type, mode and uid, but failed "
				"to read or match gid\n");
			break; 
		}
		goto error;
	}

	switch(type) {
	case 'b':
		/* FALLTHROUGH */
	case 'c':
		n = sscanf(def, "%u %u %n", &major, &minor, &bytes);
		def += bytes;

		if(n < 2) {
			ERROR("Not enough or invalid arguments in %s device "
				"pseudo file definition \"%s\"\n", type == 'b' ?
				"block" : "character", orig_def);
			if(n < 1)
				ERROR("Read filename, type, mode, uid and gid, "
					"but failed to read or match major\n");
			else
				ERROR("Read filename, type, mode, uid, gid "
					"and major, but failed to read  or "
					"match minor\n");
			goto error;
		}	
		
		if(major > 0xfff) {
			ERROR("Major %d out of range\n", major);
			goto error;
		}

		if(minor > 0xfffff) {
			ERROR("Minor %d out of range\n", minor);
			goto error;
		}
		/* FALLTHROUGH */
	case 'd':
		/* FALLTHROUGH */
	case 'm':
		/*
		 * Check for trailing junk after expected arguments
		 */
		if(def[0] != '\0') {
			ERROR("Unexpected tailing characters in pseudo file "
				"definition \"%s\"\n", orig_def);
			goto error;
		}
		break;
	case 'f':
		if(def[0] == '\0') {
			ERROR("Not enough arguments in dynamic file pseudo "
				"definition \"%s\"\n", orig_def);
			ERROR("Expected command, which can be an executable "
				"or a piece of shell script\n");
			goto error;
		}	
		break;
	default:
		ERROR("Unsupported type %c\n", type);
		goto error;
	}


	if(mode > 07777) {
		ERROR("Mode %o out of range\n", mode);
		goto error;
	}

	uid = strtoll(suid, &ptr, 10);
	if(*ptr == '\0') {
		if(uid < 0 || uid > ((1LL << 32) - 1)) {
			ERROR("Uid %s out of range\n", suid);
			goto error;
		}
	} else {
		struct passwd *pwuid = getpwnam(suid);
		if(pwuid)
			uid = pwuid->pw_uid;
		else {
			ERROR("Uid %s invalid uid or unknown user\n", suid);
			goto error;
		}
	}
		
	gid = strtoll(sgid, &ptr, 10);
	if(*ptr == '\0') {
		if(gid < 0 || gid > ((1LL << 32) - 1)) {
			ERROR("Gid %s out of range\n", sgid);
			goto error;
		}
	} else {
		struct group *grgid = getgrnam(sgid);
		if(grgid)
			gid = grgid->gr_gid;
		else {
			ERROR("Gid %s invalid uid or unknown user\n", sgid);
			goto error;
		}
	}

	switch(type) {
	case 'b':
		mode |= S_IFBLK;
		break;
	case 'c':
		mode |= S_IFCHR;
		break;
	case 'd':
		mode |= S_IFDIR;
		break;
	case 'f':
		mode |= S_IFREG;
		break;
	}

	dev = malloc(sizeof(struct pseudo_dev));
	if(dev == NULL)
		MEM_ERROR();

	dev->type = type;
	dev->mode = mode;
	dev->uid = uid;
	dev->gid = gid;
	dev->major = major;
	dev->minor = minor;
	if(type == 'f') {
		dev->command = strdup(def);
		add_pseudo_file(dev);
	}

	pseudo = add_pseudo(pseudo, dev, filename, filename);

	free(filename);
	return TRUE;

error:
	ERROR("Pseudo definitions should be of format\n");
	ERROR("\tfilename d mode uid gid\n");
	ERROR("\tfilename m mode uid gid\n");
	ERROR("\tfilename b mode uid gid major minor\n");
	ERROR("\tfilename c mode uid gid major minor\n");
	ERROR("\tfilename f mode uid command\n");
	free(filename);
	return FALSE;
}
コード例 #4
0
ファイル: pseudo.c プロジェクト: Distrotech/squashfs
/*
 * Add pseudo device target to the set of pseudo devices.  Pseudo_dev
 * describes the pseudo device attributes.
 */
struct pseudo *add_pseudo(struct pseudo *pseudo, struct pseudo_dev *pseudo_dev,
	char *target, char *alltarget)
{
	char *targname;
	int i;

	target = get_component(target, &targname);

	if(pseudo == NULL) {
		pseudo = malloc(sizeof(struct pseudo));
		if(pseudo == NULL)
			MEM_ERROR();

		pseudo->names = 0;
		pseudo->count = 0;
		pseudo->name = NULL;
	}

	for(i = 0; i < pseudo->names; i++)
		if(strcmp(pseudo->name[i].name, targname) == 0)
			break;

	if(i == pseudo->names) {
		/* allocate new name entry */
		pseudo->names ++;
		pseudo->name = realloc(pseudo->name, (i + 1) *
			sizeof(struct pseudo_entry));
		if(pseudo->name == NULL)
			MEM_ERROR();
		pseudo->name[i].name = targname;

		if(target[0] == '\0') {
			/* at leaf pathname component */
			pseudo->name[i].pseudo = NULL;
			pseudo->name[i].pathname = strdup(alltarget);
			pseudo->name[i].dev = pseudo_dev;
		} else {
			/* recurse adding child components */
			pseudo->name[i].dev = NULL;
			pseudo->name[i].pseudo = add_pseudo(NULL, pseudo_dev,
				target, alltarget);
		}
	} else {
		/* existing matching entry */
		free(targname);

		if(pseudo->name[i].pseudo == NULL) {
			/* No sub-directory which means this is the leaf
			 * component of a pre-existing pseudo file.
			 */
			if(target[0] != '\0') {
				/*
				 * entry must exist as either a 'd' type or
				 * 'm' type pseudo file
				 */
				if(pseudo->name[i].dev->type == 'd' ||
					pseudo->name[i].dev->type == 'm')
					/* recurse adding child components */
					pseudo->name[i].pseudo =
						add_pseudo(NULL, pseudo_dev,
						target, alltarget);
				else {
					ERROR_START("%s already exists as a "
						"non directory.",
						pseudo->name[i].name);
					ERROR_EXIT(".  Ignoring %s!\n",
						alltarget);
				}
			} else if(memcmp(pseudo_dev, pseudo->name[i].dev,
					sizeof(struct pseudo_dev)) != 0) {
				ERROR_START("%s already exists as a different "
					"pseudo definition.", alltarget);
				ERROR_EXIT("  Ignoring!\n");
			} else {
				ERROR_START("%s already exists as an identical "
					"pseudo definition!", alltarget);
				ERROR_EXIT("  Ignoring!\n");
			}
		} else {
			if(target[0] == '\0') {
				/*
				 * sub-directory exists, which means we can only
				 * add a pseudo file of type 'd' or type 'm'
				 */
				if(pseudo->name[i].dev == NULL &&
						(pseudo_dev->type == 'd' ||
						pseudo_dev->type == 'm')) {
					pseudo->name[i].pathname =
						strdup(alltarget);
					pseudo->name[i].dev = pseudo_dev;
				} else {
					ERROR_START("%s already exists as a "
						"different pseudo definition.",
						pseudo->name[i].name);
					ERROR_EXIT("  Ignoring %s!\n",
						alltarget);
				}
			} else
				/* recurse adding child components */
				add_pseudo(pseudo->name[i].pseudo, pseudo_dev,
					target, alltarget);
		}
	}

	return pseudo;
}
コード例 #5
0
ファイル: pseudo.c プロジェクト: rampageX/firmware-mod-kit
int read_pseudo_def(struct pseudo **pseudo, char *def)
{
	int n;
	unsigned int major = 0, minor = 0, mode;
	char filename[2048], type, suid[100], sgid[100], *ptr;
	long long uid, gid;
	struct pseudo_dev dev;

	n = sscanf(def, "%s %c %o %s %s %u %u", filename, &type, &mode, suid, sgid,
			&major, &minor);

	if(n < 5) {
		ERROR("Not enough or invalid arguments in pseudo file "
			"definition\n");
		goto error;
	}

	switch(type) {
	case 'b':
	case 'c':
		if(n < 7) {
			ERROR("Not enough or invalid arguments in pseudo file "
				"definition\n");
			goto error;
		}	
		
		if(major > 0xfff) {
			ERROR("Major %d out of range\n", major);
			goto error;
		}

		if(minor > 0xfffff) {
			ERROR("Minor %d out of range\n", minor);
			goto error;
		}

		/* fall through */
	case 'd':
		if(mode > 0777) {
			ERROR("Mode %o out of range\n", mode);
			goto error;
		}

		uid = strtoll(suid, &ptr, 10);
		if(*ptr == '\0') {
			if(uid < 0 || uid > ((1LL << 32) - 1)) {
				ERROR("Uid %s out of range\n", suid);
				goto error;
			}
		} else {
			struct passwd *pwuid = getpwnam(suid);
			if(pwuid)
				uid = pwuid->pw_uid;
			else {
				ERROR("Uid %s invalid uid or unknown user\n",
					suid);
				goto error;
			}
		}
		
		gid = strtoll(sgid, &ptr, 10);
		if(*ptr == '\0') {
			if(gid < 0 || gid > ((1LL << 32) - 1)) {
				ERROR("Gid %s out of range\n", sgid);
				goto error;
			}
		} else {
			struct group *grgid = getgrnam(sgid);
			if(grgid)
				gid = grgid->gr_gid;
			else {
				ERROR("Gid %s invalid uid or unknown user\n",
					sgid);
				goto error;
			}
		}

		break;
	default:
		ERROR("Unsupported type %c\n", type);
		goto error;
	}


	switch(type) {
	case 'b':
		mode |= S_IFBLK;
		break;
	case 'c':
		mode |= S_IFCHR;
		break;
	case 'd':
		mode |= S_IFDIR;
		break;
	}

	dev.type = type;
	dev.mode = mode;
	dev.uid = uid;
	dev.gid = gid;
	dev.major = major;
	dev.minor = minor;

	*pseudo = add_pseudo(*pseudo, &dev, filename, filename);

	return TRUE;

error:
	ERROR("Bad pseudo file definition \"%s\"\n", def);
	return FALSE;
}