void check_two(const fs_path_config* paths, const char* type_name, const char* prefix) { ASSERT_FALSE(paths == nullptr); ASSERT_FALSE(type_name == nullptr); ASSERT_FALSE(prefix == nullptr); bool check_internal = check_unique(paths, type_name, prefix); EXPECT_FALSE(check_internal); bool check_overrides = check_unique(std::string("/") + prefix + "etc/fs_config_" + type_name, prefix); EXPECT_FALSE(check_overrides); }
static bool check_unique(const std::string& config, const std::string& prefix) { int retval = false; std::string data; if (!android::base::ReadFileToString(config, &data)) return retval; const fs_path_config_from_file* pc = reinterpret_cast<const fs_path_config_from_file*>(data.c_str()); size_t len = data.size(); std::vector<const char*> paths_tmp; size_t entry_number = 0; while (len > 0) { uint16_t host_len = (len >= endof(pc, len)) ? pc->len : INT16_MAX; if (host_len > len) { GTEST_LOG_(WARNING) << config << ": truncated at entry " << entry_number << " (" << host_len << " > " << len << ")"; const std::string unknown("?"); GTEST_LOG_(WARNING) << config << ": entry[" << entry_number << "]={ " << "len=" << ((len >= endof(pc, len)) ? android::base::StringPrintf("%" PRIu16, pc->len) : unknown) << ", mode=" << ((len >= endof(pc, mode)) ? android::base::StringPrintf("0%" PRIo16, pc->mode) : unknown) << ", uid=" << ((len >= endof(pc, uid)) ? android::base::StringPrintf("%" PRIu16, pc->uid) : unknown) << ", gid=" << ((len >= endof(pc, gid)) ? android::base::StringPrintf("%" PRIu16, pc->gid) : unknown) << ", capabilities=" << ((len >= endof(pc, capabilities)) ? android::base::StringPrintf("0x%" PRIx64, pc->capabilities) : unknown) << ", prefix=" << ((len >= offsetof(fs_path_config_from_file, prefix)) ? android::base::StringPrintf( "\"%.*s...", (int)(len - offsetof(fs_path_config_from_file, prefix)), pc->prefix) : unknown) << " }"; retval = true; break; } paths_tmp.push_back(pc->prefix); pc = reinterpret_cast<const fs_path_config_from_file*>(reinterpret_cast<const char*>(pc) + host_len); len -= host_len; ++entry_number; } return check_unique(paths_tmp, config, prefix) || retval; }
int main() { char first[10] = "asdfghjklq"; char second[10] = "asdfghjkll"; if (check_unique(first,10)) { printf("%s has all unique characters\n",first); } else { printf("%s has not all unique characters\n",first); } if (check_unique(second,10)) { printf("%s has all unique characters\n",second); } else { printf("%s has not all unique characters\n",second); } return 0; }
static bool check_unique(const fs_path_config* paths, const char* type_name, const std::string& prefix) { std::string config("system/core/libcutils/fs_config.cpp:android_"); config += type_name; config += "[]"; bool retval = false; std::vector<const char*> paths_tmp; for (size_t idx = 0; paths[idx].prefix; ++idx) { if (idx > max_idx) { GTEST_LOG_(WARNING) << config << ": has no end (missing null prefix)"; retval = true; break; } paths_tmp.push_back(paths[idx].prefix); } return check_unique(paths_tmp, config, prefix) || retval; }
/************************************************************************* * MAIN ENTRY POINT FOR THE FILE-SYSTEM CHECKER * * - The different passes of the checking process ... * * Parameter : full = TRUE : Full check incl. directory tree scan * FALSE: only check_unique() then full check if * any errors occurred * Return : FALSE, if a fatal error-condition occurred * *************************************************************************/ word fscheck ( word full ) { struct buf *bpar, *bp; /* used for check_inodes() */ struct dir_elem root_de; /* For fatal error handling. This longjmp - */ /* location is used, if bread() to fixed block- */ /* numbers (like 1,2,3) fails or memory alloca- */ /* operations do not succeed. */ if ( setjmp ( term_jmp ) != 0 ) { IOdebug ("%sCHECKER INTERRUPTED DUE TO A FATAL ERROR CONDITION!", S_FATAL); IOdebug ("%s(Especially block-read and memory allocation operations)", S_FATAL); finish_checker (); return FALSE; } if ( ! init_checker () ) /* Basic initialization */ return FALSE; /*--------------- The four steps of the checking process ---------------*/ IOdebug ( "%sSTEP 1 : CHECKING BASIC DATA STRUCTURES", S_INFO ); unique_err = 0; if ( ! check_unique () ) /* Basic tests on superblock */ { /* and other unique structures */ IOdebug ("%sDURING BASIC DATA STRUCTURE CHECK", S_FATAL); finish_checker (); return FALSE; } if ( !full && !unique_err ) { finish_checker (); /* Finish checking, tidy up and */ /* unlock the server's ports */ return TRUE; /* Terminate checker process */ } IOdebug ( "%sSTEP 2 : TRAVERSING THE DIRECTORY TREE (INODE-CHECK)", S_INFO); bpar = bread ( 0, 1, 1, SAVEA ); /* Get sum-block with root-dir */ /* if read fails jmp to term_jmp */ /* Start from the file-server's */ /* root position */ memcpy ( &root_de, &bpar->b_un.b_sum->root_dir, sizeof (struct dir_elem) ); brelse ( bpar->b_tbp, TAIL ); /* Release summary block */ /* Up from this point, we get a */ /* Work on the directory tree */ if ( ! check_inodes ( &root_de , 1, 0 ) ) { IOdebug ("%sDURING SIMPLE OBJECT (INODE) CHECK", S_FATAL); finish_checker (); return FALSE; } /* Work on the bit-maps */ IOdebug ( "%sSTEP 3 : MAKE BLOCK-BASED CONNECTIVITY CHECKS", S_INFO); if ( ! check_blocks () ) { IOdebug ("%sDURING BIT-MAP AND CONNECTIVITY CHECK", S_FATAL); finish_checker (); return FALSE; } actual_path[0] = '\0'; /* Perform some final tidy-up */ /* operations */ IOdebug ("%sSTEP 4 : TIDYUP EVERYTHING AND CORRECT SUMMARY INFORMATIONS", S_INFO); if ( ! tidy_update () ) { IOdebug ("%sDURING TIDY UP OPERATION", S_FATAL); finish_checker (); return FALSE; } finish_checker (); /* Finish checking, tidy up and */ /* unlock the server's ports */ return TRUE; /* Terminate checker process */ }