code_util/main.cpp

1766 lines
50 KiB
C++
Raw Permalink Normal View History

2023-02-24 09:24:48 +00:00
// scanner.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <sys/shm.h>
#include <math.h>
#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<std::string> 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<std::string> 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 <pid> [-nrp]: to enumerate modules of process pid. -nrp is no repeating\n\
enpr [-filter *.so]: to enum all processes\n\
enth <pid>: to enumerate threads of process pid\n\
exit: to exit this APP\n\
q: quit process utility\n\
stck <pid> <tid>: 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<std::string> 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 <pid> [-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, &para);
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 <pid>\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 <pid> <tid>\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 <shm-key> [-size] [-f save-local-file]: read shared memory\n\
rmshm <shm-key>: 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 <shared-memory-key>\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 <shared-memory-key>\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 <hex-str>: parse hex-string as double\n\
fdbl <decimal>: convert a decimal to inn-code double. command: fdbl -123.456\n\
fflt <decimal>: convert a decimal to inn-code float. command: fflt -123.456\n\
flt <hex-str>: parse hex-string as float\n\
fstr <string>: convert ansi-string to inn-code\n\
fuf8 <string>: convert utf8-string to inn-code\n\
funi <string>: convert unic-string to inn-code\n\
int <hex-str>: parse hex-string as integer\n\
str <hex-str>: parse hex-string as ansi-string\n\
unic <hex-str>: parse hex-string as unicode-16-string\n\
utf8 <hex-str>: 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 <hex-string>\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 <decimal>\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 <decimal>\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 <hex-string>\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 <hex-string>\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 <hex-string>\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 <hex-string>\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 <hex-string>\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 <string>\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 <string>\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 <string>\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 <num>: perform arccos(num)\n\
add <num1> <num2> [... num_n]: perform num1 + num2 + ... + num_n\n\
asin <num>: perform arcsin(num)\n\
atan <num>: perform atan(num)\n\
cos <num>: perform cos(num)\n\
deg <num>: transform between degree and radian\n\
div <num1> <num2> [... num_n]: perform num1 / num2 / ... / num_n\n\
iam <num>: transfrom between millimeters and inches\n\
ln <num>: e ^ result = num\n\
log <num> [base = 10]: base ^ result = num\n\
mul <num1> <num2> [... num_n]: perform num1 * num2 * ... * num_n\n\
paper [paper-type <dpi>]: list all paper type, or calculate image size in with given paper and dpi\n\
pow <base> <exp>: calculate base^exp\n\
radix <integer>: print a interger into hex, decimal, oct and binary\n\
sin <num>: perform sin(num)\n\
sqrt <base> [exp]: perform base^(1/2), or base^(1/exp)\n\
sub <num1> <num2> [... num_n]: perform num1 - num2 - ... - num_n\n\
tan <num>: 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 <integer>\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 <num1> <num2> [...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 <num1> <num2> [...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 <num1> <num2> [...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 <num1> <num2> [...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 <num>\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 <num>\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 <num>\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 <num>\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 <num>\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 <num>\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 <num>\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 <num>\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 <num>\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 <num>\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 <dpi>]. 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 <base> <exp>\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 <base> [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<USBDEVQ> 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<std::mutex> lock(dev_lock_);
std::vector<USBDEVQ>::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<std::mutex> 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<std::mutex> 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: <err-no> 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**)&para) = 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 <path /home> <file Makefile or *.sh> <sys-command chmod 777 %s - '%s' is the file>
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, &para);
}
if(help)
{
printf(" recf <path /home> <file Makefile or *.sh> <sys-command chmod 777 %%s - '%%s' is the file>\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 <err-no>\n");
}
return QUIT_CMD_NONE;
}
};