static unsigned int walk_directory(struct imgspec* const spec, struct hostprog_path* const path, struct entry** previous) { struct dirent** dirlst; int dirlst_count; int dirlst_index; __u64 dir_sz = 0; __u64 dir_lvl = hostprog_path_lvls(path); dirlst_count = scandir(path->p_path, &dirlst, NULL, hostprog_scandirsort); if (dirlst_count < 0) error("failed to read \"%s\": %s", path->p_path, strerror(errno)); for (dirlst_index = 0; dirlst_index < dirlst_count; dirlst_index++) { struct dirent* dent = dirlst[dirlst_index]; /* Skip "." and ".." directories, just like mkcramfs. */ if (hostprog_path_dotdir(dent->d_name)) continue; hostprog_path_dirnamelvl(path, dir_lvl); if (hostprog_path_append(path, dent->d_name) != 0) error("failed to add a filename to the hostprog_path"); struct stat st; if (lstat(path->p_path, &st) < 0) { /* Maybe this should be an error? Files missing in the image * could possibly seem like an error to the user. */ warning("skipping \"unlstatable\" file \"%s\": %s", path->p_path, strerror(errno)); spec->sp_skipnodes++; continue; } if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { /* If the file is a regular file which can not be read, then * it might as well be skipped. * * This should also possibly be an error. */ if (access(path->p_path, R_OK) < 0) { warning("skipping unreadable file \"%s\": %s", path->p_path, strerror(errno)); spec->sp_skipnodes++; continue; } /* Completely empty files seems pretty pointless to include * in the image. */ if (!st.st_size) { message(VERBOSITY_1, ">>> skipping empty file \"%s\"", path->p_path); spec->sp_skipnodes++; continue; } } else if (!spec->sp_incsocks && S_ISSOCK(st.st_mode)) { warning("skipping socket \"%s\"", path->p_path); spec->sp_skipnodes++; continue; } /* Files should never be skipped after this point since that * would mess up the image size estimation. */ struct entry* ent = malloc(sizeof(*ent)); if (!ent) error("failed to alloc an entry for \"%s\"", path->p_path); memset(ent, 0, sizeof(*ent)); ent->e_name = strdup(dent->d_name); if (!ent->e_name) error("failed to copy the entry name for \"%s\"", path->p_path); ent->e_mode = st.st_mode; ent->e_size = st.st_size; ent->e_fd = -1; ENTRY_SET_XID(spec, ent, e_uid, st.st_uid, MICROFS_IUID_WIDTH); ENTRY_SET_XID(spec, ent, e_gid, st.st_gid, MICROFS_IGID_WIDTH); if (S_ISDIR(ent->e_mode)) { ent->e_size = walk_directory(spec, path, &ent->e_firstchild); } else if (S_ISREG(ent->e_mode) || S_ISLNK(ent->e_mode)) { if (ent->e_size > MICROFS_MAXFILESIZE) { error("\"%s\" is too big, max file size is %llu bytes", path->p_path, MICROFS_MAXFILESIZE); } else if (ent->e_size > MICROFS_MAXCRAMSIZE) { warning("\"%s\" is a big file, microfs works best with files" " smaller than %llu bytes", path->p_path, MICROFS_MAXCRAMSIZE); } ent->e_path = strdup(path->p_path); if (!ent->e_path) { error("failed to copy the entry path for \"%s\"", path->p_path); } if (spec->sp_shareblocks) { if (hostprog_stack_push(spec->sp_regstack, ent) < 0) error("failed to push an entry to the regular file stack: %s", strerror(errno)); } } else if (S_ISCHR(ent->e_mode) || S_ISBLK(ent->e_mode)) { ent->e_size = makedev_lim(major(st.st_rdev), minor(st.st_rdev), MICROFS_ISIZE_WIDTH); } else if (S_ISFIFO(ent->e_mode) || S_ISSOCK(ent->e_mode)) { ent->e_size = 0; } else { error("unexpected file mode encountered"); } /* %namelen() could actually fail here if the d_name is too * long, but that will terminate the program, so that is fine. */ dir_sz += update_upperbound(spec, ent, namelen(dent->d_name)); update_stats(spec, ent); message(VERBOSITY_1, "+ %c %s", nodtype(ent->e_mode), path->p_path); *previous = ent; previous = &ent->e_sibling; } free(dirlst); hostprog_path_dirnamelvl(path, dir_lvl); /* This should never happen, but if it ever does, it is * clearly an error. */ if (dir_sz > MICROFS_MAXDIRSIZE) { error("achievement unlocked: the directory size for \"%s\"" " is %llu bytes, the maximum supported size is %llu bytes" " - this is impressive in a very scary way", path->p_path, dir_sz, MICROFS_MAXDIRSIZE); } return dir_sz; }
static void devtable_modify_entry(struct imgspec* const spec, const char* path, unsigned long uid, unsigned long gid, mode_t mode, dev_t rdev) { char* path_dir = strdup(path); char* path_name = strdup(path); if (!path_dir || !path_name) error("failed to duplicate the path: %s", strerror(errno)); char* dir = dirname(path_dir); char* name = basename(path_name); struct entry* parent; struct entry* target; if (strcmp(dir, "/") == 0) { parent = spec->sp_root; } else if (!(parent = devtable_find_entry(spec->sp_root, dir + 1, S_IFDIR))) { error("could not find the parent for path \"%s\"", path); } if ((target = devtable_find_entry(parent, name, mode & S_IFMT))) { target->e_mode = mode; ENTRY_SET_XID(spec, target, e_uid, uid, MICROFS_IUID_WIDTH); ENTRY_SET_XID(spec, target, e_gid, gid, MICROFS_IGID_WIDTH); message(VERBOSITY_1, "(src:%s) %% %c %s", spec->sp_devtable, nodtype(target->e_mode), path); } else { target = malloc(sizeof(*target)); if (!target) error("failed to alloc an entry for \"%s\"", path); memset(target, 0, sizeof(*target)); if (S_ISREG(mode)) { error("regular file \"%s\" must exist on the disk" " - and it can not be empty", path); } target->e_fd = -1; target->e_mode = mode; ENTRY_SET_XID(spec, target, e_uid, uid, MICROFS_IUID_WIDTH); ENTRY_SET_XID(spec, target, e_gid, gid, MICROFS_IGID_WIDTH); size_t targetnamelen = namelen(name); target->e_name = strdup(name); if (!target->e_name) error("failed to copy the entry name for \"%s\"", path); target->e_size = rdev; parent->e_size += update_upperbound(spec, target, targetnamelen); update_stats(spec, target); struct entry* prev = NULL; struct entry* curr = parent->e_firstchild; while (curr && strcmp(name, curr->e_name) > 0) { prev = curr; curr = curr->e_sibling; } if (!prev) parent->e_firstchild = target; else prev->e_sibling = target; target->e_sibling = curr; target->e_firstchild = NULL; message(VERBOSITY_1, "(src:%s) + %c %s", spec->sp_devtable, nodtype(target->e_mode), path); } free(path_name); free(path_dir); }
OracleConnection::ObjectType OracleConnection::ReadSPDescriptionFromDB( const String &command, Anything &desc ) { StartTrace(OracleConnection.ReadSPDescriptionFromDB); String strErr( "ReadSPDescriptionFromDB: " ); MemChecker aCheckerLocal( "OracleConnection.ReadSPDescriptionFromDB", getEnvironment().getAllocator() ); MemChecker aCheckerGlobal( "OracleConnection.ReadSPDescriptionFromDB", coast::storage::Global()); sword attrStat; DscHandleType aDschp; if ( checkError( ( attrStat = OCIHandleAlloc( getEnvironment().EnvHandle(), aDschp.getVoidAddr(), OCI_HTYPE_DESCRIBE, 0, 0 ) ) ) ) { throw OracleException( *this, attrStat ); } Trace("after HandleAlloc, local allocator:" << reinterpret_cast<long>(getEnvironment().getAllocator())); Trace("after HandleAlloc, global allocator:" << reinterpret_cast<long>(coast::storage::Global())); OCIParam *parmh( 0 ); ObjectType aStmtType = DescribeObjectByName(command, aDschp, parmh); if ( aStmtType == TYPE_SYN ) { Trace("as we identified a synonym, we need to collect the scheme name and the referenced object name to ask for description"); text *name(0); ub4 namelen(0); String strSchemaName; attrStat = OCIAttrGet( (dvoid *) parmh, OCI_DTYPE_PARAM, (dvoid *) &name, (ub4 *) &namelen, OCI_ATTR_SCHEMA_NAME, ErrorHandle() ); if ( checkError( ( attrStat ) ) ) { throw OracleException( *this, attrStat ); } strSchemaName.Append(String( (char *) name, namelen )); Trace("SchemaName: " << strSchemaName); attrStat = OCIAttrGet( (dvoid *) parmh, OCI_DTYPE_PARAM, (dvoid *) &name, (ub4 *) &namelen, OCI_ATTR_NAME, ErrorHandle() ); if ( checkError( ( attrStat ) ) ) { throw OracleException( *this, attrStat ); } if ( strSchemaName.Length() ) { strSchemaName.Append('.'); } strSchemaName.Append(String( (char *) name, namelen )); Trace("trying to get descriptions for " << strSchemaName); aStmtType = DescribeObjectByName(strSchemaName, aDschp, parmh); } bool bIsFunction = ( aStmtType == TYPE_FUNC ); Trace("get the number of arguments and the arg list for stored " << (bIsFunction ? "function" : "procedure")) OCIParam *arglst( 0 ); ub2 numargs = 0; if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) parmh, OCI_DTYPE_PARAM, (dvoid *) &arglst, (ub4 *) 0, OCI_ATTR_LIST_ARGUMENTS, ErrorHandle() ) ) ) ) { throw OracleException( *this, attrStat ); } if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arglst, OCI_DTYPE_PARAM, (dvoid *) &numargs, (ub4 *) 0, OCI_ATTR_NUM_PARAMS, ErrorHandle() ) ) ) ) { throw OracleException( *this, attrStat ); } Trace(String("number of arguments: ") << numargs); OCIParam *arg( 0 ); text *name; ub4 namelen; ub2 dtype; OCITypeParamMode iomode; ub4 data_len; // For a procedure, we begin with i = 1; for a function, we begin with i = 0. int start = 0; int end = numargs; if ( !bIsFunction ) { ++start; ++end; } for ( int i = start; i < end; ++i ) { if ( checkError( ( attrStat = OCIParamGet( (dvoid *) arglst, OCI_DTYPE_PARAM, ErrorHandle(), (dvoid **) &arg, (ub4) i ) ) ) ) { throw OracleException( *this, attrStat ); } namelen = 0; name = 0; data_len = 0; if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &dtype, (ub4 *) 0, OCI_ATTR_DATA_TYPE, ErrorHandle() ) ) ) ) { throw OracleException( *this, attrStat ); } Trace("Data type: " << dtype) if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &name, (ub4 *) &namelen, OCI_ATTR_NAME, ErrorHandle() ) ) ) ) { throw OracleException( *this, attrStat ); } String strName( (char *) name, namelen ); // the first param of a function is the return param if ( bIsFunction && i == start ) { strName = command; Trace("Name: " << strName) } // 0 = IN (OCI_TYPEPARAM_IN), 1 = OUT (OCI_TYPEPARAM_OUT), 2 = IN/OUT (OCI_TYPEPARAM_INOUT) if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &iomode, (ub4 *) 0, OCI_ATTR_IOMODE, ErrorHandle() ) ) ) ) { throw OracleException( *this, attrStat ); } Trace("IO type: " << iomode) if ( checkError( ( attrStat = OCIAttrGet( (dvoid *) arg, OCI_DTYPE_PARAM, (dvoid *) &data_len, (ub4 *) 0, OCI_ATTR_DATA_SIZE, ErrorHandle() ) ) ) ) { throw OracleException( *this, attrStat ); } Trace("Size: " << (int)data_len) Anything param( desc.GetAllocator() ); param["Name"] = strName; param["Type"] = dtype; param["Length"] = (int) data_len; param["IoMode"] = iomode; param["Idx"] = (long) ( bIsFunction ? i + 1 : i ); desc.Append( param ); if ( checkError( ( attrStat = OCIDescriptorFree( arg, OCI_DTYPE_PARAM ) ) ) ) { throw OracleException( *this, attrStat ); } }