Example #1
0
/*
 * Return a pointer to struct parsed_filename which contains the filename.
 * Path must begin with / and not be otherwise blank (i.e. path != '/').
 * If it does not meet this condition, NULL is returned.
 */
struct parsed_filename *parse_directory(char *path){
	if (path[0] != '/' || path[1] == '\0'){
		return NULL;
	}
	
	int i = 1;
	while (path[i] != '\0' && path[i] != '/'){
		i++;
	}
	
	struct parsed_filename *current_directory_filename = malloc(sizeof(struct parsed_filename));
	
	if(!current_directory_filename){
		perror("malloc for current directory filename");
   	}
	
	current_directory_filename -> file_name = malloc((i)*sizeof(char));
	if(!current_directory_filename -> file_name){
		perror("malloc for string in current directory struct");
		exit(1);
	}
	
	strncpy(current_directory_filename -> file_name, path + 1, i-1);
	current_directory_filename -> file_name[i-1] = '\0';
	
	current_directory_filename -> next = parse_directory(path + i);
	
	return current_directory_filename;
}
static void build_image_list(const char* dirname, const char* type, xmlNodePtr node)
{
	struct image_file_data data;
	data.type = type;
	data.node = node;
	parse_directory(dirname, 0, image_list_callback, (void*)&data);
}
Example #3
0
void parse_directory(const char *dirpath) {
    DIR *dir;
    struct dirent *dentry;
    unsigned i;
    char *newpath, *extension;
    struct cue cue;
   
    dir = opendir(dirpath);
    if(!dir)
        return;
    for(;;) {
        dentry = readdir(dir);
        if(!dentry)
            break;
        if(dentry->d_name[0]=='.') {
            if(dentry->d_namlen==1 
            ||(dentry->d_namlen==2 && dentry->d_name[1]=='.'))
                continue;
        }

        asprintf(&newpath, "%s/%s", dirpath, dentry->d_name);
        extension = strrchr(dentry->d_name, '.');
        if(extension && !strcasecmp(extension+1, "cue")) {
            cue_from_file(&cue, newpath);
            export_cue_libsndfile(&cue, dirpath);
        } else {
            parse_directory(newpath);
        }
        free(newpath);
    }
    closedir(dir);

}
Example #4
0
int main()
{
  auto parsed = parse_directory(".");
  write_type_id(parsed);

  return 0;
}
Example #5
0
/**
 * @short Bulk converts all files at dirname, excepting *~, and the creates a handler for such directory.
 */
void parse_directory(const char *prefix, const char *dirname, FILE * outfd,
                     onion_assets_file * assets) {
  DIR *dir = opendir(dirname);
  if (!dir) {
    fprintf(stderr, "ERROR: Could not open directory %s, check permissions.",
            dirname);
    exit(4);
  }
  // First create other files/dirs
  struct dirent *de;
  char fullname[1024];
  while ((de = readdir(dir))) {
    if (de->d_name[0] == '.' || de->d_name[strlen(de->d_name) - 1] == '~')
      continue;
    snprintf(fullname, sizeof(fullname), "%s/%s", dirname, de->d_name);
    if (de->d_type == DT_DIR) {
      char prefix2[256];
      snprintf(prefix2, sizeof(prefix2), "%s/%s", prefix, de->d_name);
      parse_directory(prefix2, fullname, outfd, assets);
    } else
      parse_file(prefix, fullname, outfd, assets);
  }
  closedir(dir);
  // Now create current
  char *fname = funcname(prefix, NULL);
  snprintf(fullname, sizeof(fullname),
           "onion_connection_status %s(void *_, onion_request *req, onion_response *res);",
           fname);
  onion_assets_file_update(assets, fullname);
  fprintf(stderr, "Parsing directory: %s to '%s'.\n", dirname, fullname);
  fprintf(outfd,
          "onion_connection_status %s(void *_, onion_request *req, onion_response *res){\n",
          fname);
  fprintf(outfd, "  const char *path=onion_request_get_path(req);\n\n");

  dir = opendir(dirname);
  while ((de = readdir(dir))) {
    if (de->d_name[0] == '.' || de->d_name[strlen(de->d_name) - 1] == '~')
      continue;
    char *fname = funcname(prefix, de->d_name);
    if (de->d_type == DT_DIR) {
      int l = strlen(de->d_name);
      fprintf(outfd, "  if (strncmp(\"%s/\", path, %d)==0){\n", de->d_name,
              l + 1);
      fprintf(outfd, "    onion_request_advance_path(req, %d);\n", l + 1);
    } else
      fprintf(outfd, "  if (strcmp(\"%s\", path)==0){\n", de->d_name);
    fprintf(outfd, "    return %s(_, req, res);\n", fname);
    fprintf(outfd, "  }\n");
    free(fname);
  }
  closedir(dir);

  fprintf(outfd, "  return OCS_NOT_PROCESSED;\n");
  fprintf(outfd, "}\n\n");
  free(fname);
}
Example #6
0
static int dconfirm(directive_t * d)
{
	source_t * src;

	if (d->values[0] == NULL) return 0;

	d->nd = new_dir(d->values[0], d->par);
	confirm_common(d);

	if (d->values[1] != NULL) {
		src = source_string(d->values[1]);
		d->nd = parse_directory(src, d->nd);
		free(src);
	}

	return 1;
}
Example #7
0
struct basic_fileinfo find_file(char *path, char *inode_base){
	struct basic_fileinfo file_info;
	file_info.type = '\0'; //default
	file_info.inode = 0;
	if(path[0] == '\0'){
		return file_info; //perhaps an error goes here?
	}
	else if (path[0] == '/' && path[1] == '\0'){
		file_info.type = 'd';
		file_info.inode = 2;
		return file_info;
	}
	struct parsed_filename *directory_linked_list = parse_directory(path);
	if(!directory_linked_list){
		return file_info;
	}
	return search_directory(inode_base, 2, directory_linked_list);
}
Example #8
0
int main(int argc, char *argv[]) {
    DIR *dir;
    unsigned i;

    if(argc <= 1) {
        fputs("I need one or more directories "
              "to operate recursively on.\n", stderr);
        exit(EXIT_SUCCESS);
    }

    for(i=1 ; i<argc ; ++i) {
        dir = opendir(argv[i]);
        if(dir) {
            closedir(dir);
            parse_directory(argv[i]);
        } else
            fprintf(stderr, "Could not open \"%s\".\n", argv[i]);
    }
    return EXIT_SUCCESS;
}
Example #9
0
/*
 * Usage:
 *
 *      mkcramfs directory-name outfile
 *
 * where "directory-name" is simply the root of the directory
 * tree that we want to generate a compressed filesystem out
 * of.
 */
int main(int argc, char **argv)
{
	struct stat st;		/* used twice... */
	struct entry *root_entry;
	char *rom_image;
	ssize_t offset, written;
	int fd;
	/* initial guess (upper-bound) of required filesystem size */
	loff_t fslen_ub = sizeof(struct cramfs_super);
	char const *dirname, *outfile;
	u32 crc = crc32(0L, Z_NULL, 0);
	int c;			/* for getopt */

	total_blocks = 0;

	if (argc)
		progname = argv[0];

	/* command line options */
	while ((c = getopt(argc, argv, "hEe:i:n:psz")) != EOF) {
		switch (c) {
		case 'h':
			usage(0);
		case 'E':
			opt_errors = 1;
			break;
		case 'e':
			opt_edition = atoi(optarg);
			break;
		case 'i':
			opt_image = optarg;
			if (lstat(opt_image, &st) < 0) {
				perror(opt_image);
				exit(16);
			}
			image_length = st.st_size; /* may be padded later */
			fslen_ub += (image_length + 3); /* 3 is for padding */
			break;
		case 'n':
			opt_name = optarg;
			break;
		case 'p':
			opt_pad = PAD_SIZE;
			fslen_ub += PAD_SIZE;
			break;
		case 's':
			/* old option, ignored */
			break;
		case 'z':
			opt_holes = 1;
			break;
		}
	}

	if ((argc - optind) != 2)
		usage(16);
	dirname = argv[optind];
	outfile = argv[optind + 1];

	if (stat(dirname, &st) < 0) {
		perror(dirname);
		exit(16);
	}
	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);

	root_entry = calloc(1, sizeof(struct entry));
	if (!root_entry) {
		perror(NULL);
		exit(8);
	}
	root_entry->mode = st.st_mode;
	root_entry->uid = st.st_uid;
	root_entry->gid = st.st_gid;

	root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub);

	/* always allocate a multiple of blksize bytes because that's
           what we're going to write later on */
	fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1;

	if (fslen_ub > MAXFSLEN) {
		fprintf(stderr,
			"warning: guestimate of required size (upper bound) is %LdMB, but maximum image size is %uMB.  We might die prematurely.\n",
			fslen_ub >> 20,
			MAXFSLEN >> 20);
		fslen_ub = MAXFSLEN;
	}
Example #10
0
static unsigned int parse_directory(struct entry *root_entry, const char *name, struct entry **prev, loff_t *fslen_ub)
{
	struct dirent **dirlist;
	int totalsize = 0, dircount, dirindex;
	char *path, *endpath;
	size_t len = strlen(name);

	/* Set up the path. */
	/* TODO: Reuse the parent's buffer to save memcpy'ing and duplication. */
	path = malloc(len + 1 + MAX_INPUT_NAMELEN + 1);
	if (!path) {
		perror(NULL);
		exit(8);
	}
	memcpy(path, name, len);
	endpath = path + len;
	*endpath = '/';
	endpath++;

        /* read in the directory and sort */
        dircount = scandir(name, &dirlist, 0, cramsort);

	if (dircount < 0) {
		perror(name);
		exit(8);
	}

	/* process directory */
	for (dirindex = 0; dirindex < dircount; dirindex++) {
		struct dirent *dirent;
		struct entry *entry;
		struct stat st;
		int size;
		size_t namelen;

		dirent = dirlist[dirindex];

		/* Ignore "." and ".." - we won't be adding them to the archive */
		if (dirent->d_name[0] == '.') {
			if (dirent->d_name[1] == '\0')
				continue;
			if (dirent->d_name[1] == '.') {
				if (dirent->d_name[2] == '\0')
					continue;
			}
		}
		namelen = strlen(dirent->d_name);
		if (namelen > MAX_INPUT_NAMELEN) {
			fprintf(stderr,
				"Very long (%u bytes) filename `%s' found.\n"
				" Please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile.  Exiting.\n",
				namelen, dirent->d_name);
			exit(8);
		}
		memcpy(endpath, dirent->d_name, namelen + 1);

		if (lstat(path, &st) < 0) {
			perror(endpath);
			warn_skip = 1;
			continue;
		}
		entry = calloc(1, sizeof(struct entry));
		if (!entry) {
			perror(NULL);
			exit(8);
		}
		entry->name = strdup(dirent->d_name);
		if (!entry->name) {
			perror(NULL);
			exit(8);
		}
		if (namelen > 255) {
			/* Can't happen when reading from ext2fs. */

			/* TODO: we ought to avoid chopping in half
			   multi-byte UTF8 characters. */
			entry->name[namelen = 255] = '\0';
			warn_namelen = 1;
		}
		entry->mode = st.st_mode;
		entry->size = st.st_size;
//		entry->uid = st.st_uid;
		entry->uid = 0;
		if (entry->uid >= 1 << CRAMFS_UID_WIDTH)
			warn_uid = 1;
//		entry->gid = st.st_gid;
		entry->gid = 0;
		if (entry->gid >= 1 << CRAMFS_GID_WIDTH)
			/* TODO: We ought to replace with a default
                           gid instead of truncating; otherwise there
                           are security problems.  Maybe mode should
                           be &= ~070.  Same goes for uid once Linux
                           supports >16-bit uids. */
			warn_gid = 1;
		size = sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);
		*fslen_ub += size;
		if (S_ISDIR(st.st_mode)) {
			entry->size = parse_directory(root_entry, path, &entry->child, fslen_ub);
		} else if (S_ISREG(st.st_mode)) {
			/* TODO: We ought to open files in do_compress, one
			   at a time, instead of amassing all these memory
			   maps during parse_directory (which don't get used
			   until do_compress anyway).  As it is, we tend to
			   get EMFILE errors (especially if mkcramfs is run
			   by non-root).

			   While we're at it, do analagously for symlinks
			   (which would just save a little memory). */
			int fd = open(path, O_RDONLY);
			if (fd < 0) {
				perror(path);
				warn_skip = 1;
				continue;
			}
			if (entry->size) {
				if ((entry->size >= 1 << CRAMFS_SIZE_WIDTH)) {
					warn_size = 1;
					entry->size = (1 << CRAMFS_SIZE_WIDTH) - 1;
				}

				entry->uncompressed = mmap(NULL, entry->size, PROT_READ, MAP_PRIVATE, fd, 0);
				if (-1 == (int) (long) entry->uncompressed) {
					perror("mmap");
					exit(8);
				}
			}
			close(fd);
		} else if (S_ISLNK(st.st_mode)) {
			entry->uncompressed = malloc(entry->size);
			if (!entry->uncompressed) {
				perror(NULL);
				exit(8);
			}
			if (readlink(path, entry->uncompressed, entry->size) < 0) {
				perror(path);
				warn_skip = 1;
				continue;
			}
		} else if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
			/* maybe we should skip sockets */
			entry->size = 0;
		} else {
			entry->size = st.st_rdev;
			if (entry->size & -(1<<CRAMFS_SIZE_WIDTH))
				warn_dev = 1;
		}

		if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
			int blocks = ((entry->size - 1) / blksize + 1);

			/* block pointers & data expansion allowance + data */
			if(entry->size)
				*fslen_ub += (4+26)*blocks + entry->size + 3;
                }

		/* Link it into the list */
		*prev = entry;
		prev = &entry->next;
		totalsize += size;
	}
	free(path);
	free(dirlist);		/* allocated by scandir() with malloc() */
	return totalsize;
}
Example #11
0
int main(int argc, char **argv) {
  if (argc == 1)
    print_help(argv[0]);
  int i;
  char *outfile = NULL;
  char *assetfile = "assets.h";
  // First pass cancel out the options, let only the files
  for (i = 1; i < argc; i++) {
    if (strcmp(argv[i], "--help") == 0)
      print_help();
    else if (strcmp(argv[i], "-o") == 0) {
      if (i >= argc - 1) {
        fprintf(stderr, "ERROR: Need an argument for -o");
        exit(2);
      }
      outfile = argv[i + 1];
      argv[i] = NULL;           // cancel them out.
      argv[i + 1] = NULL;
      i++;
    } else if (strcmp(argv[i], "-a") == 0) {
      if (i >= argc - 1) {
        fprintf(stderr, "ERROR: Need an argument for -a");
        exit(2);
      }
      assetfile = argv[i + 1];
      argv[i] = NULL;           // cancel them out.
      argv[i + 1] = NULL;
      i++;
    }
  }

  FILE *outfd = stdout;
  if (outfile) {
    outfd = fopen(outfile, "w");
    if (!outfd) {
      perror("ERROR: Could not open output file");
      exit(2);
    }
  }
  onion_assets_file *assets = onion_assets_file_new(assetfile);

  // Some header...
  fprintf(outfd, "/** File autogenerated by opack **/\n\n");
  fprintf(outfd, "#include <onion/request.h>\n\n");
  fprintf(outfd, "#include <onion/response.h>\n\n");
  fprintf(outfd, "#include <string.h>\n\n");

  for (i = 1; i < argc; i++) {
    if (argv[i]) {
      struct stat st;
      stat(argv[i], &st);
      if (S_ISDIR(st.st_mode)) {
        parse_directory(basename(argv[1]), argv[i], outfd, assets);
      } else {
        parse_file("", argv[i], outfd, assets);
      }
    }
  }

  if (outfile) {
    fclose(outfd);
  }
  onion_assets_file_free(assets);

  return 0;
}
Example #12
0
static unsigned int parse_directory(struct entry *root_entry, const char *name, struct entry **prev, off_t *fslen_ub)
{
	struct dirent **dirlist;
	int totalsize = 0, dircount, dirindex;
	char *path, *endpath;
	size_t len = strlen(name);

	/* Set up the path. */
	/* TODO: Reuse the parent's buffer to save memcpy'ing and duplication. */
	path = malloc(len + 1 + MAX_INPUT_NAMELEN + 1);
	if (!path) {
		die(MKFS_ERROR, 1, "malloc failed");
	}
	memcpy(path, name, len);
	endpath = path + len;
	*endpath = '/';
	endpath++;

	/* read in the directory and sort */
	dircount = scandir(name, &dirlist, 0, cramsort);

	if (dircount < 0) {
		die(MKFS_ERROR, 1, "scandir failed: %s", name);
	}

	/* process directory */
	for (dirindex = 0; dirindex < dircount; dirindex++) {
		struct dirent *dirent;
		struct entry *entry;
		struct stat st;
		int size;
		size_t namelen;

		dirent = dirlist[dirindex];

		/* Ignore "." and ".." - we won't be adding them to the archive */
		if (dirent->d_name[0] == '.') {
			if (dirent->d_name[1] == '\0')
				continue;
			if (dirent->d_name[1] == '.') {
				if (dirent->d_name[2] == '\0')
					continue;
			}
		}
		namelen = strlen(dirent->d_name);
		if (namelen > MAX_INPUT_NAMELEN) {
			die(MKFS_ERROR, 0,
				"very long (%u bytes) filename found: %s\n"
				"please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile",
				namelen, dirent->d_name);
		}
		memcpy(endpath, dirent->d_name, namelen + 1);

		if (lstat(path, &st) < 0) {
			warn_skip = 1;
			continue;
		}
		entry = calloc(1, sizeof(struct entry));
		if (!entry) {
			die(MKFS_ERROR, 1, "calloc failed");
		}
		entry->name = strdup(dirent->d_name);
		if (!entry->name) {
			die(MKFS_ERROR, 1, "strdup failed");
		}
		/* truncate multi-byte UTF-8 filenames on character boundary */
		if (namelen > CRAMFS_MAXPATHLEN) {
			namelen = CRAMFS_MAXPATHLEN;
			warn_namelen = 1;
			/* the first lost byte must not be a trail byte */
			while ((entry->name[namelen] & 0xc0) == 0x80) {
				namelen--;
				/* are we reasonably certain it was UTF-8 ? */
				if (entry->name[namelen] < 0x80 || !namelen) {
					die(MKFS_ERROR, 0, "cannot truncate filenames not encoded in UTF-8");
				}
			}
			entry->name[namelen] = '\0';
		}
		entry->mode = st.st_mode;
		entry->size = st.st_size;
		entry->uid = st.st_uid;
		if (entry->uid >= 1 << CRAMFS_UID_WIDTH)
			warn_uid = 1;
		entry->gid = st.st_gid;
		if (entry->gid >= 1 << CRAMFS_GID_WIDTH)
			/* TODO: We ought to replace with a default
			   gid instead of truncating; otherwise there
			   are security problems.  Maybe mode should
			   be &= ~070.  Same goes for uid once Linux
			   supports >16-bit uids. */
			warn_gid = 1;
		size = sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);
		*fslen_ub += size;
		if (S_ISDIR(st.st_mode)) {
			entry->size = parse_directory(root_entry, path, &entry->child, fslen_ub);
		} else if (S_ISREG(st.st_mode)) {
			if (entry->size) {
				if (access(path, R_OK) < 0) {
					warn_skip = 1;
					continue;
				}
				entry->path = strdup(path);
				if (!entry->path) {
					die(MKFS_ERROR, 1, "strdup failed");
				}
				if ((entry->size >= 1 << CRAMFS_SIZE_WIDTH)) {
					warn_size = 1;
					entry->size = (1 << CRAMFS_SIZE_WIDTH) - 1;
				}
			}
		} else if (S_ISLNK(st.st_mode)) {
			entry->uncompressed = malloc(entry->size);
			if (!entry->uncompressed) {
				die(MKFS_ERROR, 1, "malloc failed");
			}
			if (readlink(path, entry->uncompressed, entry->size) < 0) {
				warn_skip = 1;
				continue;
			}
		} else if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
			/* maybe we should skip sockets */
			entry->size = 0;
		} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
			entry->size = st.st_rdev;
			if (entry->size & -(1<<CRAMFS_SIZE_WIDTH))
				warn_dev = 1;
		} else {
			die(MKFS_ERROR, 0, "bogus file type: %s", entry->name);
		}

		if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
			int blocks = ((entry->size - 1) / blksize + 1);

			/* block pointers & data expansion allowance + data */
			if (entry->size)
				*fslen_ub += (4+26)*blocks + entry->size + 3;
		}

		/* Link it into the list */
		*prev = entry;
		prev = &entry->next;
		totalsize += size;
	}
	free(path);
	free(dirlist);		/* allocated by scandir() with malloc() */
	return totalsize;
}
Example #13
0
struct stdfss_res *mkdir(int wpid, struct working_thread *thread, struct stdfss_mkdir *mkdir_cmd)
{
	struct stdfss_res *ret = NULL;
	struct smount_info *minf = NULL;
	struct sdevice_info *opening_dinf = NULL;
	char *str = NULL, *old_str = NULL, *strmatched = NULL;
	int parse_ret, dir_exists;
	struct gc_node *dir_base_node = NULL, *new_dir_base_node = NULL;
	unsigned int nodeid;

	// get dir name from smo
	str = get_string(mkdir_cmd->dir_path);

	ret = check_path(str, thread->command.command);
	if(ret != NULL) return ret;

	// get mount info
	wait_mutex(&mounted_mutex);
	minf = (struct smount_info *)lpt_getvalue_parcial_matchE(mounted, str, &strmatched);
	leave_mutex(&mounted_mutex);

	if(minf == NULL)
	{
		ret = build_response_msg(mkdir_cmd->command, STDFSSERR_DEVICE_NOT_MOUNTED);
		free(str);
		return ret;
	}

	// remove trailing '/'
	if(str[len(str)] == '/')
	{
		old_str = str;
		str = substring(str, 0, len(str) - 1);
		free(old_str);
	}

	// check file does not exist
	parse_ret = parse_directory(TRUE, &dir_base_node, OFS_NODELOCK_EXCLUSIVE | OFS_NODELOCK_BLOCKING, thread->command.command, thread, wpid, minf, str, len(strmatched), NULL, &nodeid, NULL, &dir_exists, &ret);

	if(ret != NULL) free(ret);
	ret = NULL;

	free(strmatched);
	
	if(parse_ret)
	{
		// file exists
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(str);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, dir_base_node);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_EXISTS);
	}
	if(!dir_exists)
	{
		// worng path
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(str);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_DOESNOTEXIST);
	}

	dir_base_node = thread->lastdir_parsed_node;
	
	// Create directory file
	if(!create_file(dir_base_node, str, last_index_of(str, '/') + 1, OFS_DIRECTORY_FILE, TRUE, minf, wpid, thread->command.command, &nodeid, &new_dir_base_node , OFS_NOFLAGS, &ret))
	{
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(str);
		return ret;
	}

	nfree(minf->dinf, thread->lastdir_parsed_node);
	thread->lastdir_parsed_node = NULL;
	nfree(minf->dinf, new_dir_base_node);

	free(str);


	// unlock the dir node
	unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);

	return build_response_msg(thread->command.command, STDFSSERR_OK);
}
int main(int argc, char **argv)
{
	struct stat st;		/* used twice... */
	struct entry *root_entry;
	char *rom_image;
	ssize_t offset, written;
	int fd;
	/* initial guess (upper-bound) of required filesystem size */
	loff_t fslen_ub = sizeof(struct cramfs_super);
	char const *dirname, *outfile;
	u32 crc;
	int c;			/* for getopt */
	char *ep;		/* for strtoul */
	char *comp_method_str;

	total_blocks = 0;

	if (argc)
		progname = argv[0];

	/* command line options */
	while ((c = getopt(argc, argv, "hEe:i:b:c:n:psvz")) != EOF) {
		switch (c) {
		case 'h':
			usage(MKFS_OK);
		case 'E':
			opt_errors = 1;
			break;
		case 'e':
			errno = 0;
			opt_edition = strtoul(optarg, &ep, 10);
			if (errno || optarg[0] == '\0' || *ep != '\0')
				usage(MKFS_USAGE);
			break;
		case 'i':
			opt_image = optarg;
			if (lstat(opt_image, &st) < 0) {
				die(MKFS_ERROR, 1, "lstat failed: %s", opt_image);
			}
			image_length = st.st_size; /* may be padded later */
			fslen_ub += (image_length + 3); /* 3 is for padding */
			break;
		case 'b':
			blksize = atoi(optarg);
			/* blksize must be 4096 * 2 ^ n, where n is an
			 * integer between 0 and 4 (blksize_bit calculated
			 * here is this n). */
			for (blksize_bit = 0; blksize_bit < 5; blksize_bit++)
			{
				if (blksize ==
				    DEFAULT_PAGE_CACHE_SIZE << blksize_bit)
				{
				    break;
				}
			}

			if (blksize_bit > 4)
			{
				die(MKFS_ERROR,
				    0,"wrong or unsupported block size\n");
			}
			break;
		case 'n':
			opt_name = optarg;
			break;
		case 'p':
			opt_pad = PAD_SIZE;
			fslen_ub += PAD_SIZE;
			break;
		case 's':
			/* old option, ignored */
			break;
		case 'v':
			opt_verbose++;
			break;
		case 'z':
			opt_holes = 1;
			break;
		case 'c':
			if (!strcmp(optarg, "none"))
			    opt_compression = CRAMFS_FLAG_COMP_METHOD_NONE;
			else if (!strcmp(optarg, "gzip"))
			    opt_compression = CRAMFS_FLAG_COMP_METHOD_GZIP;
			else if (!strcmp(optarg, "lzma"))
			    opt_compression = CRAMFS_FLAG_COMP_METHOD_LZMA;
			else
			{
			   die(MKFS_ERROR,
			       0,"wrong or unsupported compression method\n"); 
			}
		}
	}

	if ((argc - optind) != 2)
		usage(MKFS_USAGE);
	dirname = argv[optind];
	outfile = argv[optind + 1];

	printf("Using a blocksize of %d bytes.\n", blksize);
	switch (opt_compression)
	{
	case CRAMFS_FLAG_COMP_METHOD_NONE:
		comp_method_str = "none";
		break;
	case CRAMFS_FLAG_COMP_METHOD_GZIP:
		comp_method_str = "gzip";
		break;
	case CRAMFS_FLAG_COMP_METHOD_LZMA:
		comp_method_str = "lzma";
		break;
	default:
		comp_method_str = "unknown";
		break;
	}
	    
	printf("Using block compression method: %s\n", comp_method_str);

	if (stat(dirname, &st) < 0) {
		die(MKFS_USAGE, 1, "stat failed: %s", dirname);
	}
	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
	if (fd < 0) {
		die(MKFS_USAGE, 1, "open failed: %s", outfile);
	}

	root_entry = calloc(1, sizeof(struct entry));
	if (!root_entry) {
		die(MKFS_ERROR, 1, "calloc failed");
	}
	root_entry->mode = st.st_mode;
	root_entry->uid = st.st_uid;
	root_entry->gid = st.st_gid;

	root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub);

	/* always allocate a multiple of blksize bytes because that's
	   what we're going to write later on */
	fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1;

	if (fslen_ub > MAXFSLEN) {
		fprintf(stderr,
			"warning: estimate of required size (upper bound) is %LdMB, but maximum image size is %uMB, we might die prematurely\n",
			fslen_ub >> 20,
			MAXFSLEN >> 20);
		fslen_ub = MAXFSLEN;
	}
Example #15
0
struct stdfss_res *mkdevice(int wpid, struct working_thread *thread, struct stdfss_mkdevice *mkdevice_cmd)
{
	struct stdfss_res *ret = NULL;
	struct smount_info *minf = NULL;
	struct sdevice_info *opening_dinf = NULL;
	char *str = NULL, *strmatched = NULL;
	int parse_ret, dir_exists;
	struct gc_node *dir_base_node = NULL, *device_base_node = NULL;
	unsigned int *block = NULL;
	unsigned int nodeid;
	
	// get device file name from smo
	str = get_string(mkdevice_cmd->path_smo);
	
	ret = check_path(str, thread->command.command);
	if(ret != NULL) return ret;

	char *devstr = get_string(mkdevice_cmd->service_name);

	ret = check_path(devstr, thread->command.command);
	if(ret != NULL)
	{
		free(str);
		return ret;
	}

	// check path is ok
	if(str[len(str)] == '/')
	{
		free(str);
		free(devstr);
		return build_response_msg(thread->command.command, STDFSSERR_INVALID_COMMAND_PARAMS);
	}

	// get mount info
	wait_mutex(&mounted_mutex);
	minf = (struct smount_info *)lpt_getvalue_parcial_matchE(mounted, str, &strmatched);
	leave_mutex(&mounted_mutex);

	if(minf == NULL)
	{
		free(str);
		free(devstr);
		return build_response_msg(mkdevice_cmd->command, STDFSSERR_DEVICE_NOT_MOUNTED);
	}

	// check file does not exist
	parse_ret = parse_directory(TRUE, &dir_base_node, OFS_NODELOCK_EXCLUSIVE | OFS_NODELOCK_BLOCKING, thread->command.command, thread, wpid, minf, str, len(strmatched), NULL, &nodeid, NULL, &dir_exists, &ret);

	if(ret != NULL) free(ret);
	ret = NULL;

	if(parse_ret)
	{
		// file exists
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(strmatched);
		free(str);
		free(devstr);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, dir_base_node);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_EXISTS);
	}

	if(!dir_exists)
	{
		// worng path
		if(thread->lastdir_parsed_node != NULL)
		{
			nfree(minf->dinf, thread->lastdir_parsed_node);
			thread->lastdir_parsed_node = NULL;
		}
		free(strmatched);
		free(str);
		free(devstr);
		return build_response_msg(thread->command.command, STDFSSERR_FILE_DOESNOTEXIST);
	}

	dir_base_node = nref(minf->dinf, thread->lastdir_parsed_node->nodeid);
	
	free(strmatched);

	// Create device file
	if(!create_file(dir_base_node, str, last_index_of(str, '/') + 1, OFS_DEVICE_FILE, TRUE, minf, wpid, thread->command.command, &nodeid, &device_base_node, OFS_NOFLAGS , &ret))
	{
		nfree(minf->dinf, thread->lastdir_parsed_node);
		nfree(minf->dinf, dir_base_node);
		thread->lastdir_parsed_node = NULL;
		
		free(str);
		free(devstr);
		return ret;
	}
	
	nfree(minf->dinf, thread->lastdir_parsed_node);
	nfree(minf->dinf, dir_base_node);
	thread->lastdir_parsed_node = NULL;
	
	// get a free block 
	block = get_free_blocks(1, TRUE, minf, thread->command.command, wpid, &ret);
	if(ret != NULL)
	{
		free(str);
		free(devstr);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, device_base_node);
		return ret;
	}

	free(str);

	clear_dir_buffer(thread->directory_buffer.buffer);

	// write buffer
	/*
		int LOGIC DEVICE ID: internal ID on the service (4 BYTES)
		int service name size; (4 BYTES)
		char SERVICE NAME[]: name of the device driver (zero terminated devstring) 
	*/
	*((unsigned int *)thread->directory_buffer.buffer) = (unsigned int)mkdevice_cmd->logic_deviceid;
	*((unsigned int *)(thread->directory_buffer.buffer + 4)) = len(devstr);
	mem_copy((unsigned char *)devstr, ((unsigned char *)thread->directory_buffer.buffer + 8), len(devstr) + 1);

	free(devstr);

	write_buffer((char *)thread->directory_buffer.buffer, OFS_DIR_BUFFERSIZE, *block, thread->command.command, wpid, minf, &ret);
	if(ret != NULL)
	{
		free_block(TRUE, TRUE, *block, minf, thread->command.command, wpid, &ret);
		free(block);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, device_base_node);
		return ret;
	}

	// update node
	device_base_node->n.file_size = 8 + len(devstr) + 1;
	device_base_node->n.blocks[0] = *block;

	if(!write_node(device_base_node, minf, wpid, thread->command.command, &ret) || ret != NULL)
	{
		free_block(TRUE, TRUE, *block, minf, thread->command.command, wpid, &ret);
		free(block);
		unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);
		nfree(minf->dinf, device_base_node);
		return ret;
	}

	nfree(minf->dinf, device_base_node);

	// unlock device node
	unlock_node(wpid, FALSE, OFS_LOCKSTATUS_OK);	

	return build_response_msg(thread->command.command, STDFSSERR_OK);
}
Example #16
0
/* Parse or skip over the vnode data */
static afs_uint32
parse_vdata(XFILE * X, unsigned char *tag, tagged_field * field,
	    afs_uint32 value, tag_parse_info * pi, void *g_refcon,
	    void *l_refcon)
{
    dump_parser *p = (dump_parser *) g_refcon;
    afs_vnode *v = (afs_vnode *) l_refcon;
    static char *symlink_buf = 0;
    static int symlink_size = 0;
    afs_uint32 r;

    if ((r = ReadInt32(X, &v->size)))
	return r;
    v->field_mask |= F_VNODE_SIZE;

    if (v->size) {
	v->field_mask |= F_VNODE_DATA;
	if ((r = xftell(X, &v->d_offset)))
	    return r;
	if (p->print_flags & DSPRINT_VNODE)
	    printf("%s%d (0x%08x) bytes at %s (0x%s)\n", field->label,
		   v->size, v->size, decimate_int64(&v->d_offset, 0),
		   hexify_int64(&v->d_offset, 0));

	switch (v->type) {
	case vSymlink:
	    if (v->size > symlink_size) {
		if (symlink_buf)
		    symlink_buf = realloc(symlink_buf, v->size + 1);
		else
		    symlink_buf = (char *)malloc(v->size + 1);
		symlink_size = symlink_buf ? v->size : 0;
	    }
	    if (symlink_buf) {
		if ((r = xfread(X, symlink_buf, v->size)))
		    return r;
		symlink_buf[v->size] = 0;
		if (p->print_flags & DSPRINT_VNODE)
		    printf(" Target:       %s\n", symlink_buf);
	    } else {
		/* Call the callback here, because it's non-fatal */
		if (p->cb_error)
		    (p->cb_error) (ENOMEM, 0, p->err_refcon,
				   "Out of memory reading symlink");
		if ((r = xfskip(X, v->size)))
		    return r;
	    }
	    break;

	case vDirectory:
	    if (p->cb_dirent || (p->print_flags & DSPRINT_DIR)) {
		if ((r = parse_directory(X, p, v, v->size, 0)))
		    return r;
		break;
	    }

	default:
	    if ((r = xfskip(X, v->size)))
		return r;
	}
    } else if (p->print_flags & DSPRINT_VNODE) {
	printf("%sEmpty\n", field->label);
    }
    if (p->repair_flags & DSFIX_VDSYNC) {
	r = resync_vnode(X, p, v, 10, 15);
	if (r)
	    return r;
    }
    return ReadByte(X, tag);
}
Example #17
0
/*
 * Usage:
 *
 *      mkcramfs directory-name outfile
 *
 * where "directory-name" is simply the root of the directory
 * tree that we want to generate a compressed filesystem out
 * of.
 */
int main(int argc, char **argv)
{
	struct stat st;		/* used twice... */
	struct entry *root_entry;
	char *rom_image;
	ssize_t offset, written;
	int fd;
	/* initial guess (upper-bound) of required filesystem size */
	off_t fslen_ub = sizeof(struct cramfs_super);
	char const *dirname, *outfile;
	u32 crc;
	int c;			/* for getopt */
	char *ep;		/* for strtoul */
	FILE *devtable = NULL;

	total_blocks = 0;

	if (argc)
		progname = argv[0];

	/* command line options */
	while ((c = getopt(argc, argv, "hEe:i:n:psvzD:q")) != EOF) {
		switch (c) {
		case 'h':
			usage(MKFS_OK);
		case 'E':
			opt_errors = 1;
			break;
		case 'e':
			errno = 0;
			opt_edition = strtoul(optarg, &ep, 10);
			if (errno || optarg[0] == '\0' || *ep != '\0')
				usage(MKFS_USAGE);
			break;
		case 'i':
			opt_image = optarg;
			if (lstat(opt_image, &st) < 0) {
				error_msg_and_die("lstat failed: %s", opt_image);
			}
			image_length = st.st_size; /* may be padded later */
			fslen_ub += (image_length + 3); /* 3 is for padding */
			break;
		case 'n':
			opt_name = optarg;
			break;
		case 'p':
			opt_pad = PAD_SIZE;
			fslen_ub += PAD_SIZE;
			break;
		case 's':
			/* old option, ignored */
			break;
		case 'v':
			opt_verbose++;
			break;
		case 'z':
			opt_holes = 1;
			break;
		case 'q':
			opt_squash = 1;
			break;
		case 'D':
			devtable = xfopen(optarg, "r");
			if (fstat(fileno(devtable), &st) < 0)
				perror_msg_and_die(optarg);
			if (st.st_size < 10)
				error_msg_and_die("%s: not a proper device table file\n", optarg);
			break;
		}
	}

	if ((argc - optind) != 2)
		usage(MKFS_USAGE);
	dirname = argv[optind];
	outfile = argv[optind + 1];

	if (stat(dirname, &st) < 0) {
		error_msg_and_die("stat failed: %s", dirname);
	}
	fd = xopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);

	root_entry = xcalloc(1, sizeof(struct entry));
	root_entry->mode = st.st_mode;
	root_entry->uid = st.st_uid;
	root_entry->gid = st.st_gid;

	root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub);

	if (devtable) {
		parse_device_table(devtable, root_entry, &fslen_ub);
	}

	/* always allocate a multiple of blksize bytes because that's
           what we're going to write later on */
	fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1;

	if (fslen_ub > MAXFSLEN) {
		fprintf(stderr,
			"warning: estimate of required size (upper bound) is %LdMB, but maximum image size is %uMB, we might die prematurely\n",
			fslen_ub >> 20,
			MAXFSLEN >> 20);
		fslen_ub = MAXFSLEN;
	}