// scanner.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include #include #include #include #include #include #include #include "cmd.h" #include "usb_manager.h" #define CONST_E 2.7182818284590452353602874713527f #define CONST_PI 3.1415926535897932384626433832795f #define MM_PER_INCH 25.4f #define IS_EQUAL(v, t) ((v - t) >= -.00001f && (v - t) <= .00001f) namespace proc_util { static bool is_match(const char* str, const char* pattern) { std::vector parts; std::string all(pattern); size_t pos = all.find("*"); while(pos != std::string::npos) { if(pos) parts.push_back(all.substr(0, pos)); all.erase(0, pos + 1); pos = all.find("*"); } if(!all.empty()) parts.push_back(all); for(pos = 0; pos < parts.size(); ++pos) { str = strstr(str, parts[pos].c_str()); if(!str) break; str += parts[pos].length(); } return pos == parts.size(); } static bool found_proc(uint64_t pid, const char* path, void* param) { struct { uint32_t cnt = 0; std::string filter = ""; }*ptr; *((void**)&ptr) = param; if(ptr->filter.empty() || is_match(path, ptr->filter.c_str())) printf("%d - %ld: %s\n", ++ptr->cnt, pid, path); return true; } static bool found_modules(const char* path, bool is_dir, void* param) { uint32_t* cnt = (uint32_t*)param; printf("%d - %s\n", ++cnt[0], path); return true; } static bool found_modules_norepeat(const char* path, bool is_dir, void* param) { struct { uint32_t cnt; std::vector modules; }*data = nullptr; *(void**)&data = param; if (std::find(data->modules.begin(), data->modules.end(), path) == data->modules.end()) { printf("%d - %s\n", ++data->cnt, path); data->modules.push_back(path); } return true; } static bool on_found_thread(uint64_t tid, void* start_addr, void* param) { uint32_t* cnt = (uint32_t*)param; printf("%d - %p(%u): starting at %p\n", ++cnt[0], tid, tid, start_addr); return true; } static bool on_stack(uint64_t off, const char* module, void* param) { uint32_t* cnt = (uint32_t*)param; printf("%d - %s + %p\n", ++cnt[0], module, off); return true; } // -proc static CONSOLE_ROUTINE(print_help) { printf("\ usage: enmo [-nrp]: to enumerate modules of process pid. -nrp is no repeating\n\ enpr [-filter *.so]: to enum all processes\n\ enth : to enumerate threads of process pid\n\ exit: to exit this APP\n\ q: quit process utility\n\ stck : to get thread(tid) calling stack of process pid\n\n\ "); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(enum_module) { if(cmd->count()) { uint64_t pid = sys_util::to_int(cmd->parameter(0)); bool nrp = cmd->count() >= 2 && strcmp(cmd->parameter(1), "-nrp") == 0; if(nrp) { struct { uint32_t cnt = 0; std::vector modules; }data; sys_util::enum_modules(found_modules_norepeat, &data, pid); } else { uint32_t cnt = 0; sys_util::enum_modules(found_modules, &cnt, pid); } } else printf(" enmo [-nrp]\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(enum_process) { struct { uint32_t cnt = 0; std::string filter = ""; }para; if(cmd->parameter("-filter")) { para.filter = cmd->parameter("-filter"); } sys_util::enum_processes(found_proc, ¶); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(enum_thread) { if(cmd->count()) { uint32_t cnt = 0; sys_util::enum_threads(sys_util::to_int(cmd->parameter(0)), on_found_thread, &cnt); } else printf(" enth \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(get_stack) { if(cmd->count() >= 2) { uint32_t cnt = 0; sys_util::get_thread_callstack(sys_util::to_int(cmd->parameter(0)), sys_util::to_int(cmd->parameter(1)), on_stack, &cnt); } else printf(" stck \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(run_console) { quit_cmd quit = QUIT_CMD_NONE; std::string pre_cmd = cmd->to_command_line(); console_dispatcher me; me.add_command_routine("enmo", enum_module); me.add_command_routine("enpr", enum_process); me.add_command_routine("enth", enum_thread); me.add_command_routine("stck", get_stack); me.set_unhandled_routine(print_help); quit = me.run("hgutil-proc", pre_cmd.c_str()); return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE; } } namespace kernel_obj { // -kobj static quit_cmd print_help(cmd_line* cmd, void* param) { printf("\ usage: enmsg: enumerate all shared memories\n\ ensem: enumerate all semaphores\n\ enshm: enumerate all shared memories\n\ rdshm [-size] [-f save-local-file]: read shared memory\n\ rmshm : remove shared-memory which defined by 'shm-key'\n\ exit: to exit this APP\n\ q: quit process utility\n\ \n\ "); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(read_shm) { if(cmd->count()) { key_t k = (key_t)sys_util::to_int(cmd->parameter(0)); int shm = shmget(k, 0, 0600); if(shm == -1) { printf(" Failed: shmget(%p, 0, 0600) = %d(%s)\n", k, errno, strerror(errno)); } else { size_t size = sys_util::get_page_size(); FILE *dst = nullptr; char *buf = nullptr; std::string file(""); if(cmd->parameter("-size")) size = sys_util::to_int(cmd->parameter("-size")); if(cmd->parameter("-f")) { file = sys_util::to_abs_path(getenv("PWD"), cmd->parameter("-f")); dst = fopen(file.c_str(), "wb"); if(!dst) printf(" Failed to create target file(%s) = %d(%s)\n", file.c_str(), errno, strerror(errno)); else printf(" Write down to file '%s'\n", file.c_str()); } buf = (char*)shmat(shm, 0, 0); if(buf == (char*)-1) { printf(" Failed to map shared memory(%p) = %d(%s)\n", k, errno, strerror(errno)); if(dst) { fclose(dst); remove(file.c_str()); } } else { if(dst) { size = fwrite(buf, 1, size, dst); fclose(dst); printf(" %u bytes saved into file '%s'\n", size, file.c_str()); } else console_dispatcher::print_sector((uint8_t*)buf, size); shmdt(buf); } } } else printf(" rmshm \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(remove_shm) { if(cmd->count()) { key_t k = (key_t)sys_util::to_int(cmd->parameter(0)); int shm = shmget(k, 0, 0600); if(shm == -1) { printf("Failed: shmget(%p, 0, 0600) = %d(%s), try system command 'ipcs -M %s'\n", k, errno, strerror(errno), cmd->parameter(0)); } else { struct shmid_ds ds = {0}; if(shmctl(shm, IPC_RMID, &ds)) { printf("Failed: shmctl(%d, IPC_RMID, (shmid_ds*)%p) = %d(%s)\n", shm, &ds, k, errno, strerror(errno)); } else printf("Remove shared-memory(%p) success.\n", k); } } else printf(" rmshm \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(enum_shm) { system("ipcs -m"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(enum_sem) { system("ipcs -s"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(enum_msg) { system("ipcs -q"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(run_console) { quit_cmd quit = QUIT_CMD_NONE; std::string pre_cmd = cmd->to_command_line(); console_dispatcher me; me.add_command_routine("rmshm", remove_shm); me.add_command_routine("rdshm", read_shm); me.add_command_routine("enshm", enum_shm); me.add_command_routine("enmsg", enum_msg); me.add_command_routine("ensem", enum_sem); me.set_unhandled_routine(print_help); quit = me.run("hgutil-kobj", pre_cmd.c_str()); return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE; } } namespace mem_util { // -mem static uint32_t handle(int32_t argc, char** argv) { uint64_t total = 0, avail = 0; uint32_t page = sys_util::get_page_size(), err = sys_util::get_memory_info(&total, &avail); char cpu[256] = {0}; sys_util::get_inf_file_data("/proc/cpuinfo", sizeof(cpu) - 1, "model name\t:%s %s %s %s @ %s", cpu, cpu + 50, cpu + 100, cpu + 150, cpu + 200); printf("CPU model: %s %s %s %s @ %s\n", cpu, cpu + 50, cpu + 100, cpu + 150, cpu + 200); if(err) printf("get memory info failed: %d(%s)\n", err, strerror(err)); else { printf("Memory total: %s\n", sys_util::format_readable_bytes(total).c_str()); printf("Memory avail: %s\n", sys_util::format_readable_bytes(avail).c_str()); } printf("Page size: %d\n", page); return err; } static quit_cmd run_console(cmd_line* cmd, void* param) { quit_cmd quit = QUIT_CMD_NONE; handle(0, nullptr); return quit; } } namespace parse_util { // we assume the console locale is in UTF-8 here ... static CONSOLE_ROUTINE(print_help) { printf("\ usage: dbl : parse hex-string as double\n\ fdbl : convert a decimal to inn-code double. command: fdbl -123.456\n\ fflt : convert a decimal to inn-code float. command: fflt -123.456\n\ flt : parse hex-string as float\n\ fstr : convert ansi-string to inn-code\n\ fuf8 : convert utf8-string to inn-code\n\ funi : convert unic-string to inn-code\n\ int : parse hex-string as integer\n\ str : parse hex-string as ansi-string\n\ unic : parse hex-string as unicode-16-string\n\ utf8 : parse hex-string as utf8-string\n\ exit: to exit this APP\n\ q: quit process utility\n\ "); return QUIT_CMD_NONE; } static std::string from_hex_str(const char* hex) { const char* h = hex, *t = nullptr; uint64_t v = sys_util::from_hex_str(h, &t); char buf[80] = {0}; int off = 0; std::string in(""); while(t > h) { if((t - h) % 2) v <<= 4; off = 8; for(int i = 0; i < (t - h + 1) / 2; ++i, v >>= 8) buf[--off] = v & 0xff; in += std::string(buf + off, 8 - off); h = t; v = sys_util::from_hex_str(h, &t); } in.append(8, '\0'); return std::move(in); } static CONSOLE_ROUTINE(as_double) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); printf("Result: %f\n", *(double*)&val[0]); } else printf(" dbl \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(from_double) { if(cmd->count()) { double val = atof(cmd->parameter(0)); printf("Result: "); for(int i = 0; i < sizeof(val); ++i) printf("%02X", ((uint8_t*)&val)[i]); printf("\n"); } else printf(" fdbl \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(from_float) { if(cmd->count()) { float val = atof(cmd->parameter(0)); printf("Result: "); for(int i = 0; i < sizeof(val); ++i) printf("%02X", ((uint8_t*)&val)[i]); printf("\n"); } else printf(" fflt \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(as_float) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); printf("Result: %f\n", *(float*)&val[0]); } else printf(" flt \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(as_integer) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); if(val.length() - 8 <= 4) { int n = 0; if(val.length() - 8 == 1) n = (char)val[0]; else if(val.length() - 8 == 2) n = *(short*)&val[0]; else n = *(int*)&val[0]; printf("Result: %d(%u)\n", n, n); } else printf("Result: %ld\n", *(uint64_t*)&val[0]); } else printf(" int \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(as_ansi_str) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); printf("Result: '%s'\n", sys_util::transform_between_gbk_and_utf8(val.c_str(), true).c_str()); } else printf(" str \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(as_unicode) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); printf("Result: '%s'\n", sys_util::transform_between_utf16_and_utf8(val.c_str(), val.length(), true).c_str()); } else printf(" unic \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(as_utf8) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); printf("Result: '%s'\n", val.c_str()); } else printf(" utf8 \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(from_ansi) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); val = sys_util::transform_between_gbk_and_utf8(val.c_str(), false); printf("Result: "); for(int i = 0; i < val.length(); ++i) printf("%02X", (uint8_t)val[i]); printf("\n"); } else printf(" fstr \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(from_utf8) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); printf("Result: "); for(int i = 0; i < val.length(); ++i) printf("%02X", (uint8_t)val[i]); printf("\n"); } else printf(" fuf8 \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(from_unicode) { if(cmd->count()) { std::string val(from_hex_str(cmd->parameter(0))); val = sys_util::transform_between_utf16_and_utf8(val.c_str(), val.length(), false); printf("Result: "); for(int i = 0; i < val.length(); ++i) printf("%02X", (uint8_t)val[i]); printf("\n"); } else printf(" funi \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(run_console) { quit_cmd quit = QUIT_CMD_NONE; std::string pre_cmd = cmd->to_command_line(); console_dispatcher me; me.add_command_routine("dbl", as_double); me.add_command_routine("fdbl", from_double); me.add_command_routine("fflt", from_float); me.add_command_routine("flt", as_float); me.add_command_routine("int", as_integer); me.add_command_routine("str", as_ansi_str); me.add_command_routine("unic", as_unicode); me.add_command_routine("utf8", as_utf8); me.add_command_routine("fstr", from_ansi); me.add_command_routine("fuf8", from_utf8); me.add_command_routine("funi", from_unicode); me.set_unhandled_routine(print_help); quit = me.run("hgutil-parse", pre_cmd.c_str()); return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE; } } namespace calculator { static std::string format_readable_integer(uint64_t v, const char* fmt, int align = 4, const char* sep = " ", bool patch = true) { char buf[80] = {0}; std::string ret(""); if(strcmp(fmt, "%lb") == 0) { while(v) { ret.insert(0, v & 1 ? "1" : "0"); v >>= 1; } if(ret.empty()) ret = "0"; } else { sprintf(buf, fmt, v); ret = buf; } if(patch && (ret.length() % align)) { std::string fill(""); fill.append(align, '0'); ret.insert(0, fill); ret.erase(0, ret.length() % align); } for(int i = ret.length() - align; i > 0; i -= align) ret.insert(i, sep); return std::move(ret); } static bool is_valid_double(double v) { return isnan(v) == 0; } static double pick_decimal(const char*& dec, bool* ok) { double sign = 1.0f, radix = 1.0f, val = .0f, coef = 10.0f; if(ok) *ok = true; if(*dec == '-') { sign = -1.0f; dec++; } while(*dec) { if(*dec == '.') { if(radix < 1.0f) { if(ok) *ok = false; break; } radix = .1f; coef = 1.0f; } else if(*dec == '-') break; else if(*dec >= '0' && *dec <= '9') { val *= coef; val += (*dec - '0') * radix; if(radix < 1.0f) radix *= .1f; } else break; dec++; } if(!is_valid_double(val) && ok) *ok = false; return val * sign; } static double calc_exp(const char* exp, bool *ok = nullptr) { bool good = true; double val = .0f, sign = 1.0f; std::string sop(""); if(!ok) ok = &good; while(*exp) { double hi = .0f; bool calc = false; if(*exp == '(') { const char* end = sys_util::pick_simple_block(exp, ')'); if(!end) { *ok = false; printf("Invalid expression: '%s'\n", exp); break; } std::string sub(exp + 1, end - exp - 1); sys_util::trim_left(sub); sys_util::trim_right(sub); hi = calc_exp(sub.c_str(), ok); if(!ok[0]) break; exp = end + 1; calc = true; } else if(*exp == '-') { sign = -1.0f; exp++; } else if(*exp == '.' || (*exp >= '0' && *exp <= '9')) { // number ... hi = pick_decimal(exp, ok); calc = true; } if(!ok[0]) { printf("Invalid expression.\n"); break; } if(calc) { hi *= sign; sign = 1.0f; } } return val; } static CONSOLE_ROUTINE(print_help) { printf("\ usage: acos : perform arccos(num)\n\ add [... num_n]: perform num1 + num2 + ... + num_n\n\ asin : perform arcsin(num)\n\ atan : perform atan(num)\n\ cos : perform cos(num)\n\ deg : transform between degree and radian\n\ div [... num_n]: perform num1 / num2 / ... / num_n\n\ iam : transfrom between millimeters and inches\n\ ln : e ^ result = num\n\ log [base = 10]: base ^ result = num\n\ mul [... num_n]: perform num1 * num2 * ... * num_n\n\ paper [paper-type ]: list all paper type, or calculate image size in with given paper and dpi\n\ pow : calculate base^exp\n\ radix : print a interger into hex, decimal, oct and binary\n\ sin : perform sin(num)\n\ sqrt [exp]: perform base^(1/2), or base^(1/exp)\n\ sub [... num_n]: perform num1 - num2 - ... - num_n\n\ tan : perform tan(num)\n\ exit: to exit this APP\n\ q: quit process utility\n\ "); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(radix) { if(cmd->count()) { const char* end = nullptr; uint64_t v(sys_util::to_int(cmd->parameter(0), &end)); if(end == cmd->parameter(0)) printf("Invalid interger: %s\n", cmd->parameter(0)); else { std::string bin(format_readable_integer(v, "%lX")); printf("Hex: %s\n", bin.c_str()); bin = format_readable_integer(v, "%ld", 3, ",", false); printf("Dec: %s\n", bin.c_str()); bin = format_readable_integer(v, "%lo", 3); printf("Oct: %s\n", bin.c_str()); bin = format_readable_integer(v, "%lb"); printf("Bin: %s\n", bin.c_str()); } } else printf(" radix \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(calculate) { std::string exp(cmd->to_command_line()); double val = .0f; bool ok = true; sys_util::trim_left(exp); sys_util::trim_right(exp); val = calc_exp(exp.c_str(), &ok); if(ok) printf("Result: %f\n", val); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(add) { if(cmd->count() >= 2) { const char* para = cmd->parameter(0); bool ok = true; double v = pick_decimal(para, &ok), sum = .0f; int ind = 0; while(ok && *para == 0) { sum += v; if(!is_valid_double(sum)) { printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind)); return QUIT_CMD_NONE; } if(ind + 1 >= cmd->count()) break; para = cmd->parameter(++ind); v = pick_decimal(para, &ok); } if(ok && *para == 0) printf("Result: %f\n", sum); else printf("Invalid number: %s\n", cmd->parameter(ind)); } else printf(" add [...num_n]\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(sub) { if(cmd->count() >= 2) { const char* para = cmd->parameter(0); bool ok = true; double v = pick_decimal(para, &ok), sum = .0f; int ind = 0; while(ok && *para == 0) { if(ind == 0) sum = v; else sum -= v; if(!is_valid_double(sum)) { printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind)); return QUIT_CMD_NONE; } if(ind + 1 >= cmd->count()) break; para = cmd->parameter(++ind); v = pick_decimal(para, &ok); } if(ok && *para == 0) printf("Result: %f\n", sum); else printf("Invalid number: %s\n", cmd->parameter(ind)); } else printf(" sub [...num_n]\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(mul) { if(cmd->count() >= 2) { const char* para = cmd->parameter(0); bool ok = true; double v = pick_decimal(para, &ok), sum = 1.0f; int ind = 0; while(ok && *para == 0) { sum *= v; if(!is_valid_double(sum)) { printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind)); return QUIT_CMD_NONE; } if(ind + 1 >= cmd->count()) break; para = cmd->parameter(++ind); v = pick_decimal(para, &ok); } if(ok && *para == 0) printf("Result: %f\n", sum); else printf("Invalid number: %s\n", cmd->parameter(ind)); } else printf(" add [...num_n]\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(div) { if(cmd->count() >= 2) { const char* para = cmd->parameter(0); bool ok = true; double v = pick_decimal(para, &ok), sum = .0f; int ind = 0; while(ok && *para == 0) { if(ind == 0) sum = v; else sum /= v; if(!is_valid_double(sum)) { printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind)); return QUIT_CMD_NONE; } if(ind + 1 >= cmd->count()) break; para = cmd->parameter(++ind); v = pick_decimal(para, &ok); } if(ok && *para == 0) printf("Result: %f\n", sum); else printf("Invalid number: %s\n", cmd->parameter(ind)); } else printf(" sub [...num_n]\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(inch_and_mm) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok) { printf("%fmm = %finch\n", v, v / MM_PER_INCH); printf("%finch = %fmm\n", v, v * MM_PER_INCH); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" iam \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_log) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok), vb = 10.0f; if(*oper == 0 && ok && v > .0f) { if(cmd->count() >= 2) { oper = cmd->parameter(1); vb = pick_decimal(oper, &ok); if(*oper || !ok || vb <= .0f) { printf("Invalid number: %s\n", cmd->parameter(1)); return QUIT_CMD_NONE; } } printf("Result: %f\n", log(v) / log(vb)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" log \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_ln) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok && v > .0f) { printf("Result: %f\n", log(v) / log(CONST_E)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" log \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_degree) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok) { printf("%f degree = %f radian\n", v, v / 180.0f * CONST_PI); printf("%f radian = %f degree\n", v, v / CONST_PI * 180.0f); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" deg \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_sin) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok) { printf("Result in degree: %f\n", sin(v / 180.0f * CONST_PI)); printf("Result in radian: %f\n", sin(v)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" sin \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_cos) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok) { printf("Result in degree: %f\n", cos(v / 180.0f * CONST_PI)); printf("Result in radian: %f\n", cos(v)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" cos \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_tan) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok) { printf("Result in degree: %f\n", tan(v / 180.0f * CONST_PI)); printf("Result in radian: %f\n", tan(v)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" tan \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_asin) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok && v >= -1.0f && v <= 1.0f) { printf("Result in degree: %f\n", asin(v) / CONST_PI * 180.0f); printf("Result in radian: %f\n", asin(v)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" asin \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_acos) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok && v >= -1.0f && v <= 1.0f) { printf("Result in degree: %f\n", acos(v) / CONST_PI * 180.0f); printf("Result in radian: %f\n", acos(v)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" acos \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_atan) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok); if(*oper == 0 && ok && v >= -1.0f && v <= 1.0f) { printf("Result in degree: %f\n", atan(v) / CONST_PI * 180.0f); printf("Result in radian: %f\n", atan(v)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" atan \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(paper) { struct { std::string type; float w; float h; }papers[] = { {"A3", 297.0, 420.0}, {"A4", 210.0, 297.0}, {"A5", 148.0, 210.0}, {"A6", 105.0, 148.0}, {"B4", 257.0, 364.0}, {"B5", 182.0, 257.0}, {"JIS-B5", 176.0, 250.0}, {"B6", 125.0, 176.0} }; if(cmd->count() == 0) { printf("Paper-type\tSize (mm)\n"); for(auto& v: papers) printf(" %s %f * %f\n", v.type.c_str(), v.w, v.h); } else { bool help = true; if(cmd->count() >= 2) { const char* str = cmd->parameter(1); bool ok = true; double dpi = pick_decimal(str, &ok); if(ok && *str == 0 && dpi > .0f) { for(auto& v: papers) { if(v.type == cmd->parameter(0)) { double w = v.w / MM_PER_INCH * dpi + .999f, h = v.h / MM_PER_INCH * dpi + .999f; printf("Paper '%s' in DPI(%f) image size(pixel): %d * %d\n", v.type.c_str(), dpi, (int)w, (int)h); help = false; break; } } } else { printf("Invalid DPI: %s\n", cmd->parameter(1)); help = false; } } if(help) { printf(" paper [paper-type ]. paper type now support following:\n "); for(auto& v: papers) printf("%s ", v.type.c_str()); printf("\n"); } } return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_pow) { if(cmd->count() >= 2) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok), e = .0f; if(*oper == 0 && ok) { oper = cmd->parameter(1); e = pick_decimal(oper, &ok); if(*oper == 0 && ok) { printf("Result: %f\n", pow(v, e)); } else printf("Invalid number: %s\n", cmd->parameter(1)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" pow \n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(func_sqrt) { if(cmd->count()) { const char* oper = cmd->parameter(0); bool ok = true; double v = pick_decimal(oper, &ok), e = .5f; if(*oper == 0 && ok) { if(cmd->count() >= 2) { oper = cmd->parameter(1); e = pick_decimal(oper, &ok); if(*oper == 0 && ok && !IS_EQUAL(e, .0f)) { e = 1.0f / e; } else { ok = false; printf("Invalid number: %s\n", cmd->parameter(1)); } } if(ok) printf("Result: %f\n", pow(v, e)); } else printf("Invalid number: %s\n", cmd->parameter(0)); } else printf(" sqrt [exp]\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(run_console) { quit_cmd quit = QUIT_CMD_NONE; std::string pre_cmd = cmd->to_command_line(); console_dispatcher me; me.add_command_routine("add", add); me.add_command_routine("sub", sub); me.add_command_routine("mul", mul); me.add_command_routine("div", div); me.add_command_routine("iam", inch_and_mm); me.add_command_routine("ln", func_ln); me.add_command_routine("log", func_log); me.add_command_routine("deg", func_degree); me.add_command_routine("cos", func_cos); me.add_command_routine("sin", func_sin); me.add_command_routine("tan", func_tan); me.add_command_routine("acos", func_acos); me.add_command_routine("asin", func_asin); me.add_command_routine("atan", func_atan); me.add_command_routine("paper", paper); me.add_command_routine("radix", radix); me.add_command_routine("pow", func_pow); me.add_command_routine("sqrt", func_sqrt); me.set_unhandled_routine(print_help); quit = me.run("hgutil-calc", pre_cmd.c_str()); return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE; } } namespace top { static CONSOLE_ROUTINE(print_help); static CONSOLE_ROUTINE(clear_screen); static CONSOLE_ROUTINE(quit_me); static CONSOLE_ROUTINE(quit_all); static CONSOLE_ROUTINE(system_call); static CONSOLE_ROUTINE(recursive_file_oper); static CONSOLE_ROUTINE(error_message); }; namespace usb { struct { int vid; int pid; }g_scanner[] = { {0x31c9, 0x8200}, {0x31c9, 0x8420}, {0x31c9, 0x8429}, {0x31c9, 0x8520}, {0x31c9, 0x8529}, {0x31c9, 0x8620}, {0x31c9, 0x8629}, {0x31c9, 0x8730}, {0x31c9, 0x8739}, {0x2903, 0x1000}, {0x2903, 0x1002}, {0x2903, 0x7000}, {0x2903, 0x7002}, {0x2903, 0x7039}, {0x2903, 0x8000}, {0x2903, 0x9000}, {0x3308, 0x6006}, {0x3308, 0x6005}, {0x3308, 0x0238}, {0x3308, 0x0138}, {0X05DA, 0x9220}, {0x3072, 0x100}, {0x3072, 0x139}, {0x3072, 0x200}, {0x3072, 0x239}, {0x3072, 0x300}, {0x3072, 0x302}, {0x3072, 0x339}, {0x3072, 0x400}, {0x3072, 0x402}, {0x3072, 0x439}, {0x064B, 0x7823} }; typedef struct _usb_device_que { int vid = 0; int pid = 0; libusb_device* device = nullptr; usb_io* io = nullptr; bool operator==(const libusb_device* dev) { return dev == device; } }USBDEVQ, *LPUSBDEVQ; std::vector devs_; std::mutex dev_lock_; void usb_event_function(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user) // usb_ver_h.usb_ver_l { std::lock_guard lock(dev_lock_); std::vector::iterator it = std::find(devs_.begin(), devs_.end(), device); if (USB_EVENT_DEVICE_ARRIVED == ev) { if(it == devs_.end()) { USBDEVQ dev; dev.vid = vid; dev.pid = pid; dev.device = device; devs_.push_back(dev); } else { it->vid = vid; it->pid = pid; } } else if (USB_EVENT_DEVICE_LEFT == ev) { if(it != devs_.end()) { if(it->io) it->io->release(); devs_.erase(it); } } } static bool is_scanner(int vid, int pid) { for(auto& v: g_scanner) { if(v.vid == vid && v.pid == pid) return true; } return false; } static void resolve(USBDEVQ& dev) { std::string msg(""); usb_io* io = nullptr; int err = usb_manager::instance()->open(dev.device, &io, &msg); if(err) { printf(" Open failed: %d - %s\n", dev.vid, dev.pid, err, msg.c_str()); printf(" To resolve this device, try RESTART it!\n\n"); if(io) io->release(); return; } int size = 1024 * 1024, len = size, total = 0; char *buf = new char[size]; io->set_timeout(100); printf(" First: Clear bulk end-point ..."); while((err = io->read_bulk(buf, &len)) == 0) { total += len; len = size; } printf(" %d byte(s) cleared with last error(%d).\n", total, err); printf(" Second: Clear interrupt end-point ..."); total = 0; len = size; io->set_timeout(100); while((err = io->read_interrupt(buf, &len)) == 0) { total += len; len = size; } printf(" %d byte(s) cleared with last error(%d).\n", total, err == SCANNER_ERR_TIMEOUT ? 0 : err); // try get SN: printf(" Last: try get serial number ... "); total = sizeof(len); len = 0; err = io->control_io(0x40, 0x64, 18, 0, &len, &total); if(err == SCANNER_ERR_TIMEOUT) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); err = io->control_io(0x40, 0x64, 18, 0, &len, &total); } if(err) printf("write command failed: %d\n", err); else { len = size; err = io->read_bulk(buf, &len); buf[len] = 0; printf("%s (%d)\n", buf, err == SCANNER_ERR_TIMEOUT ? 0 : err); } delete[] buf; printf("\n"); io->release(); } static CONSOLE_ROUTINE(print_help) { printf("\ usage: trouble: to resolve problem with HGs scanner\n\ lsusb: to print all USB devices\n\ exit: to exit this APP\n\ q: quit process utility\n\ "); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(trouble) { std::lock_guard lock(dev_lock_); int cnt = 0; for(auto& v : devs_) { if(!is_scanner(v.vid, v.pid)) continue; printf(" %d: Resolve %04X:%04X ...\n", ++cnt, v.vid, v.pid); resolve(v); } if(cnt == 0) printf(" No scanner found!\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(list_usb) { std::lock_guard lock(dev_lock_); int cnt = 0; for(auto& v : devs_) printf(" %d: %04X:%04X\n", ++cnt, v.vid, v.pid); if(cnt == 0) printf(" No USB device found!\n"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(usb_tool) { usb_manager::instance()->register_hotplug(&usb_event_function, nullptr); console_dispatcher me; me.add_command_routine("trouble", &trouble); me.add_command_routine("lsusb", &list_usb); me.set_unhandled_routine(print_help); quit_cmd ret = me.run("hgutil-usb"); return ret == QUIT_CMD_QUIT_ALL ? ret : QUIT_CMD_NONE; } } int32_t main(int32_t argc, char *argv[]) { // hgutil -proc int err = 0; console_dispatcher::add_supper_command_routine("clear", &top::clear_screen); console_dispatcher::add_supper_command_routine("exit", &top::quit_all); console_dispatcher::add_supper_command_routine("q", &top::quit_me); console_dispatcher::add_supper_command_routine("sys", &top::system_call); console_dispatcher::add_supper_command_routine("errm", &top::error_message); console_dispatcher top; top.add_command_routine("proc", proc_util::run_console); top.add_command_routine("kobj", kernel_obj::run_console); top.add_command_routine("mem", mem_util::run_console); top.add_command_routine("parse", parse_util::run_console); top.add_command_routine("calc", calculator::run_console); top.add_command_routine("recf", top::recursive_file_oper); top.add_command_routine("usb", usb::usb_tool); top.set_unhandled_routine(top::print_help); top.run("hgutil"); return 0; } namespace top { static CONSOLE_ROUTINE(print_help) { printf("\ usage: calc: calculator utility\n\ clear: clear screen\n\ errm: print error message of 'err-no'\n\ kobj: named kernel objects(shared memory, event...) utility\n\ mem: memory utility\n\ parse: parse inner-code as readable target\n\ proc: process utilities\n\ recf: recursive execute system command on files\n\ usb : usb utilities\n\ q: exit\n\ sys: invoke system command\n\n\ "); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(clear_screen) { system("clear"); return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(quit_me) { return QUIT_CMD_QUIT_ME; } static CONSOLE_ROUTINE(quit_all) { return QUIT_CMD_QUIT_ALL; } static CONSOLE_ROUTINE(system_call) { std::string cmdl(cmd->to_command_line()); system(cmdl.c_str()); return QUIT_CMD_NONE; } bool is_wildcard_match(const char* str, const char* pattern, int str_len, int patt_len) { int str_ind = 0, pattern_ind = 0, star = -1, m = 0; if (str_len == -1) str_len = strlen(str); if (patt_len == -1) patt_len = strlen(pattern); while (str_ind < str_len) { if (pattern_ind < patt_len && (str[str_ind] == pattern[pattern_ind] || pattern[pattern_ind] == '?')) { str_ind++; pattern_ind++; } else if (pattern_ind < patt_len && pattern[pattern_ind] == '*') { star = pattern_ind++; m = str_ind; } else if (star != -1) { pattern_ind = star + 1; str_ind = ++m; } else return false; } while (pattern_ind < patt_len && pattern[pattern_ind] == '*') pattern_ind++; return pattern_ind == patt_len; } static bool is_match(const char* val, const char* pattern) { if(strstr(pattern, "*")) { return is_wildcard_match(val, pattern, strlen(val), strlen(pattern)); } else { return strcmp(val, pattern) == 0; } } static bool on_file_found(const char* path, bool is_dir, void* param) { if(is_dir) return true; struct { std::string pattern; std::string syscmd; }*para = nullptr; const char* name = strrchr(path, '/'); if(name++ == nullptr) name = path; *((void**)¶) = param; if(is_match(name, para->pattern.c_str())) { std::string cmd(para->syscmd), file(path); size_t pos = cmd.find("%s"); if(file.find(" ") != std::string::npos) { file += "\""; file.insert(0, "\""); } cmd.replace(pos, 2, file); printf(" %s = %d\n", cmd.c_str(), system(cmd.c_str())); } return true; } static CONSOLE_ROUTINE(recursive_file_oper) { // recf bool help = true; if(cmd->count() > 3) { std::string path(cmd->parameter(0)), file(cmd->parameter(1)), syscmd(""); struct { std::string pattern; std::string syscmd; }para; cmd->remove(0); cmd->remove(0); para.syscmd = cmd->to_command_line(); para.pattern = std::move(file); help = para.syscmd.find("%s") == std::string::npos; if(!help) sys_util::enum_files(path.c_str(), on_file_found, ¶); } if(help) { printf(" recf \n"); } return QUIT_CMD_NONE; } static CONSOLE_ROUTINE(error_message) { if(cmd->count()) { printf(" error %d: %s\n", atoi(cmd->parameter(0)), strerror(atoi(cmd->parameter(0)))); } else { printf(" errm \n"); } return QUIT_CMD_NONE; } };