/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_platform_directory_main(tb_int_t argc, tb_char_t** argv) { #if 1 // home tb_char_t home[TB_PATH_MAXN] = {0}; if (tb_directory_home(home, sizeof(home))) tb_trace_i("home: %s", home); // current tb_char_t current[TB_PATH_MAXN] = {0}; if (tb_directory_current(current, sizeof(current))) tb_trace_i("current: %s", current); // temporary tb_char_t temporary[TB_PATH_MAXN] = {0}; if (tb_directory_temporary(temporary, sizeof(temporary))) tb_trace_i("temporary: %s", temporary); #elif 0 // current tb_char_t current[TB_PATH_MAXN] = {0}; if (tb_directory_current(current, sizeof(current))) tb_trace_i("current: %s", current); // current tb_directory_walk(argv[1]? argv[1] : current, tb_true, tb_true, tb_directory_walk_func, tb_null); #elif 0 tb_directory_remove(argv[1]); #else // tb_directory_walk(argv[1], tb_true, tb_true, tb_directory_walk_func, tb_null); tb_directory_copy(argv[1], argv[2]); #endif return 0; }
/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_int_t xm_os_curdir(lua_State* lua) { // check tb_assert_and_check_return_val(lua, 0); // done os.curdir() tb_char_t path[TB_PATH_MAXN]; if (tb_directory_current(path, sizeof(path))) lua_pushstring(lua, path); else lua_pushnil(lua); // ok return 1; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_coroutine_http_server_main(tb_int_t argc, tb_char_t** argv) { // done tb_socket_ref_t sock = tb_null; do { // init socket sock = tb_socket_init(TB_SOCKET_TYPE_TCP, TB_IPADDR_FAMILY_IPV4); tb_assert_and_check_break(sock); // bind socket tb_ipaddr_t addr; tb_ipaddr_set(&addr, tb_null, TB_DEMO_PORT, TB_IPADDR_FAMILY_IPV4); if (!tb_socket_bind(sock, &addr)) break; // listen socket if (!tb_socket_listen(sock, 1000)) break; // init the root directory if (argv[1]) tb_strlcpy(g_rootdir, argv[1], sizeof(g_rootdir)); else tb_directory_current(g_rootdir, sizeof(g_rootdir)); // only data? if (!tb_file_info(g_rootdir, tb_null)) g_onlydata = tb_true; // trace tb_trace_i("%s: %s", g_onlydata? "data" : "rootdir", g_rootdir); #if TB_DEMO_CPU > 1 // start workers for multi-threads tb_size_t count = TB_DEMO_CPU - 1; while (count--) tb_thread_init(tb_null, tb_demo_coroutine_worker, sock, 0); #endif // start worker tb_demo_coroutine_worker(sock); } while (0); // exit socket if (sock) tb_socket_exit(sock); sock = tb_null; // ok return 0; }
static tb_bool_t xm_machine_main_get_project_directory(xm_machine_impl_t* impl, tb_char_t* path, tb_size_t maxn) { // check tb_assert_and_check_return_val(impl && path && maxn, tb_false); // done tb_bool_t ok = tb_false; do { // attempt to get it from the environment variable first tb_char_t data[TB_PATH_MAXN] = {0}; if ( !tb_environment_first("XMAKE_PROJECT_DIR", data, sizeof(data)) || !tb_path_absolute(data, path, maxn)) { // get it from the current directory if (!tb_directory_current(path, maxn)) break; } // trace tb_trace_d("project: %s", path); // save the directory to the global variable: _PROJECT_DIR lua_pushstring(impl->lua, path); lua_setglobal(impl->lua, "_PROJECT_DIR"); // ok ok = tb_true; } while (0); // failed? if (!ok) tb_printf("error: not found the project directory!\n"); // ok? return ok; }
tb_char_t const* tb_path_relative_to(tb_char_t const* root, tb_char_t const* path, tb_char_t* data, tb_size_t maxn) { // check tb_assert_and_check_return_val(path && data && maxn, tb_null); // trace tb_trace_d("path: %s", path); // the root is the current and the path is absolute? return path directly if (!root && !tb_path_is_absolute(path)) { // copy it tb_strlcpy(data, path, maxn); // translate it return tb_path_translate(data, 0, maxn)? data : tb_null; } // get the absolute path tb_size_t path_size = 0; tb_char_t path_absolute[TB_PATH_MAXN]; tb_size_t path_maxn = sizeof(path_absolute); path = tb_path_absolute(path, path_absolute, path_maxn); path_size = tb_strlen(path); tb_assert_and_check_return_val(path && path_size && path_size < path_maxn, tb_null); // trace tb_trace_d("path_absolute: %s", path); // get the absolute root tb_size_t root_size = 0; tb_char_t root_absolute[TB_PATH_MAXN]; tb_size_t root_maxn = sizeof(root_absolute); if (root) { // get the absolute root root = tb_path_absolute(root, root_absolute, root_maxn); root_size = tb_strlen(root); } else { // get the current directory if (!(root_size = tb_directory_current(root_absolute, root_maxn))) return tb_null; // translate it if (!(root_size = tb_path_translate(root_absolute, root_size, root_maxn))) return tb_null; root = root_absolute; } tb_assert_and_check_return_val(root && root_size && root_size < root_maxn, tb_null); // trace tb_trace_d("root_absolute: %s", root); // same directory? return "." if (path_size == root_size && !tb_strncmp(path, root, root_size)) { // check tb_assert_and_check_return_val(maxn >= 2, "."); // return "." data[0] = '.'; data[1] = '\0'; return data; } // append separator if (path_size + 1 < path_maxn) { path_absolute[path_size++] = TB_PATH_SEPARATOR; path_absolute[path_size] = '\0'; } if (root_size + 1 < root_maxn) { root_absolute[root_size++] = TB_PATH_SEPARATOR; root_absolute[root_size] = '\0'; } // find the common leading directory tb_char_t const* p = path; tb_char_t const* q = root; tb_long_t last = -1; for (; *p && *q && *p == *q; q++, p++) { // save the last separator if (*p == TB_PATH_SEPARATOR) last = q - root; } // is different directory or outside the windows drive root? using the absolute path if (last <= 0 || (last == 2 && root[1] == ':')) { // the path size tb_size_t size = tb_min(path_size - 1, maxn); // copy it tb_strncpy(data, path, size); data[size] = '\0'; } // exists same root? else { // count the remaining levels in root tb_size_t count = 0; tb_char_t const* l = root + last + 1; for (; *l; l++) { if (*l == TB_PATH_SEPARATOR) count++; } // append "../" or "..\\" tb_char_t* d = data; tb_char_t* e = data + maxn; while (count--) { if (d + 3 < e) { d[0] = '.'; d[1] = '.'; d[2] = TB_PATH_SEPARATOR; d += 3; } } // append the left path l = path + last + 1; while (*l && d < e) *d++ = *l++; // remove the last separator if (d > data) d--; // end *d = '\0'; } // trace tb_trace_d("relative: %s", data); // ok? return data; }
tb_char_t const* tb_path_absolute_to(tb_char_t const* root, tb_char_t const* path, tb_char_t* data, tb_size_t maxn) { // check tb_assert_and_check_return_val(path && data && maxn, tb_null); // trace tb_trace_d("path: %s", path); // the path is absolute? if (tb_path_is_absolute(path)) { // copy it tb_strlcpy(data, path, maxn); // translate it return tb_path_translate(data, 0, maxn)? data : tb_null; } // get the root directory tb_size_t size = 0; if (root) { // copy it size = tb_strlcpy(data, root, maxn); tb_assert_and_check_return_val(size < maxn, tb_null); } else { // get the current directory if (!(size = tb_directory_current(data, maxn))) return tb_null; } // translate the root directory size = tb_path_translate(data, size, maxn); // trace tb_trace_d("root: %s, size: %lu", data, size); // is windows path? skip the drive prefix tb_char_t* absolute = data; if (size > 2 && tb_isalpha(absolute[0]) && absolute[1] == ':' && absolute[2] == TB_PATH_SEPARATOR) { // skip it absolute += 2; size -= 2; } // path => data tb_char_t const* p = path; tb_char_t const* t = p; tb_char_t* q = absolute + size; tb_char_t const* e = absolute + maxn - 1; while (1) { if (tb_path_is_separator(*p) || !*p) { // the item size tb_size_t n = p - t; // ..? remove item if (n == 2 && t[0] == '.' && t[1] == '.') { // find the last separator for (; q > absolute && *q != TB_PATH_SEPARATOR; q--) ; // strip it *q = '\0'; } // .? continue it else if (n == 1 && t[0] == '.') ; // append item else if (n && q + 1 + n < e) { *q++ = TB_PATH_SEPARATOR; tb_strncpy(q, t, n); q += n; } // empty item? remove repeat else if (!n) ; // too small? else { // trace tb_trace_e("the data path is too small for %s", path); return tb_null; } // break tb_check_break(*p); // next t = p + 1; } // next p++; } // end if (q > absolute) *q = '\0'; // root? else { *q++ = TB_PATH_SEPARATOR; *q = '\0'; } // trace tb_trace_d("absolute: %s", data); // ok? return data; }
/* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t tb_demo_stream_main(tb_int_t argc, tb_char_t** argv) { // done tb_option_ref_t option = tb_null; tb_stream_ref_t istream = tb_null; tb_stream_ref_t ostream = tb_null; tb_stream_ref_t pstream = tb_null; do { // init option option = tb_option_init("stream", "the stream demo", g_options); tb_assert_and_check_break(option); // done option if (tb_option_done(option, argc - 1, &argv[1])) { // debug & verbose tb_bool_t debug = tb_option_find(option, "debug"); tb_bool_t verbose = tb_option_find(option, "no-verbose")? tb_false : tb_true; // done url if (tb_option_find(option, "url")) { // init istream istream = tb_stream_init_from_url(tb_option_item_cstr(option, "url")); tb_assert_and_check_break(istream); // ctrl http if (tb_stream_type(istream) == TB_STREAM_TYPE_HTTP) { // enable gzip? if (tb_option_find(option, "gzip")) { // auto unzip if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_AUTO_UNZIP, 1)) break; // need gzip if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_HEAD, "Accept-Encoding", "gzip,deflate")) break; } // enable debug? if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_HEAD_FUNC, debug? tb_demo_stream_head_func : tb_null)) break; // custem header? if (tb_option_find(option, "header")) { // init tb_string_t key; tb_string_t val; tb_string_init(&key); tb_string_init(&val); // done tb_bool_t k = tb_true; tb_char_t const* p = tb_option_item_cstr(option, "header"); while (*p) { // is key? if (k) { if (*p != ':' && !tb_isspace(*p)) tb_string_chrcat(&key, *p++); else if (*p == ':') { // skip ':' p++; // skip space while (*p && tb_isspace(*p)) p++; // is val now k = tb_false; } else p++; } // is val? else { if (*p != ';') tb_string_chrcat(&val, *p++); else { // skip ';' p++; // skip space while (*p && tb_isspace(*p)) p++; // set header if (tb_string_size(&key) && tb_string_size(&val)) { if (debug) tb_printf("header: %s: %s\n", tb_string_cstr(&key), tb_string_cstr(&val)); if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_HEAD, tb_string_cstr(&key), tb_string_cstr(&val))) break; } // is key now k = tb_true; // clear key & val tb_string_clear(&key); tb_string_clear(&val); } } } // set header if (tb_string_size(&key) && tb_string_size(&val)) { if (debug) tb_printf("header: %s: %s\n", tb_string_cstr(&key), tb_string_cstr(&val)); if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_HEAD, tb_string_cstr(&key), tb_string_cstr(&val))) break; } // exit tb_string_exit(&key); tb_string_exit(&val); } // keep alive? if (tb_option_find(option, "keep-alive")) { if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_HEAD, "Connection", "keep-alive")) break; } // post-data? if (tb_option_find(option, "post-data")) { tb_char_t const* post_data = tb_option_item_cstr(option, "post-data"); tb_hize_t post_size = tb_strlen(post_data); if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_METHOD, TB_HTTP_METHOD_POST)) break; if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_POST_DATA, post_data, post_size)) break; if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_POST_FUNC, tb_demo_http_post_func)) break; if (debug) tb_printf("post: %llu\n", post_size); } // post-file? else if (tb_option_find(option, "post-file")) { tb_char_t const* url = tb_option_item_cstr(option, "post-file"); if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_METHOD, TB_HTTP_METHOD_POST)) break; if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_POST_URL, url)) break; if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_POST_FUNC, tb_demo_http_post_func)) break; if (debug) tb_printf("post: %s\n", url); } } // set range if (tb_option_find(option, "range")) { tb_char_t const* p = tb_option_item_cstr(option, "range"); if (p) { // the bof tb_hize_t eof = 0; tb_hize_t bof = tb_atoll(p); while (*p && tb_isdigit(*p)) p++; if (*p == '-') { p++; eof = tb_atoll(p); } if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_HTTP_SET_RANGE, bof, eof)) break; } } // set timeout if (tb_option_find(option, "timeout")) { tb_size_t timeout = tb_option_item_uint32(option, "timeout"); if (!tb_stream_ctrl(istream, TB_STREAM_CTRL_SET_TIMEOUT, timeout)) break; } // print verbose info if (verbose) tb_printf("open: %s: ..\n", tb_option_item_cstr(option, "url")); // open istream if (!tb_stream_open(istream)) { // print verbose info if (verbose) tb_printf("open: %s\n", tb_state_cstr(tb_stream_state(istream))); break; } // print verbose info if (verbose) tb_printf("open: ok\n"); // init ostream if (tb_option_find(option, "more0")) { // the path tb_char_t const* path = tb_option_item_cstr(option, "more0"); // init ostream = tb_stream_init_from_file(path, TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_BINARY | TB_FILE_MODE_TRUNC); // print verbose info if (verbose) tb_printf("save: %s\n", path); } else { // the name tb_char_t const* name = tb_strrchr(tb_option_item_cstr(option, "url"), '/'); if (!name) name = tb_strrchr(tb_option_item_cstr(option, "url"), '\\'); if (!name) name = "/stream.file"; // the path tb_char_t path[TB_PATH_MAXN] = {0}; if (tb_directory_current(path, TB_PATH_MAXN)) tb_strcat(path, name); else break; // init file ostream = tb_stream_init_from_file(path, TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_BINARY | TB_FILE_MODE_TRUNC); // print verbose info if (verbose) tb_printf("save: %s\n", path); } tb_assert_and_check_break(ostream); // the limit rate tb_size_t limitrate = 0; if (tb_option_find(option, "limitrate")) limitrate = tb_option_item_uint32(option, "limitrate"); // save it tb_hong_t save = 0; tb_demo_context_t context = {0}; context.verbose = verbose; if ((save = tb_transfer_done(istream, ostream, limitrate, tb_demo_stream_save_func, &context)) < 0) break; } else tb_option_help(option); } else tb_option_help(option); } while (0); // exit pstream if (pstream) tb_stream_exit(pstream); pstream = tb_null; // exit istream if (istream) tb_stream_exit(istream); istream = tb_null; // exit ostream if (ostream) tb_stream_exit(ostream); ostream = tb_null; // exit option if (option) tb_option_exit(option); option = tb_null; return 0; }