/* * 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); }
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); }
int main() { auto parsed = parse_directory("."); write_type_id(parsed); return 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); }
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; }
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); }
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; }
/* * 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; }
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; }
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; }
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; }
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; }
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); }
/* 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); }
/* * 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; }