int main(int argc, char *argv[]) { void *context = NULL; int rc = -1; tc_res res; tc_file *tcf; /* Locate and use the default config file. Please update the config * file to the correct NFS server. */ readlink("/proc/self/exe", exe_path, PATH_MAX); snprintf(tc_config_path, PATH_MAX, "%s/../../../config/vfs.proxy.conf", dirname(exe_path)); fprintf(stderr, "using config file: %s\n", tc_config_path); /* Initialize TC services and daemons */ context = tc_init(tc_config_path, DEFAULT_LOG_FILE, 77); if (context == NULL) { NFS4_ERR("Error while initializing tc_client using config " "file: %s; see log at %s", tc_config_path, DEFAULT_LOG_FILE); return EIO; } /* Read the file; nfs4_readv() will open it first if needed. */ tcf = tc_open(TC_TEST_NFS_FILE0, O_RDWR, 0); if (tcf->fd < 0) { NFS4_DEBUG("Cannot open %s", TC_TEST_NFS_FILE0); } rc = tc_close(tcf); if (rc < 0) { NFS4_DEBUG("Cannot close %d", tcf->fd); } tcf = tc_open(TC_TEST_NFS_FILE1, O_WRONLY | O_CREAT, 0); if (tcf->fd < 0) { NFS4_DEBUG("Cannot open %s", TC_TEST_NFS_FILE1); } rc = tc_close(tcf); if (rc < 0) { NFS4_DEBUG("Cannot close %d", tcf->fd); } tc_deinit(context); return res.err_no; }
//------------------------------------------------------------------------------- // tc_start //------------------------------------------------------------------------------- err_t ICACHE_FLASH_ATTR tc_init(void) { err_t err = ERR_USE; tc_close(); TCP_SERV_CFG * p = tcpsrv_init_client3(); // tcpsrv_init(3) if (p != NULL) { // изменим конфиг на наше усмотрение: p->max_conn = 3; // =0 - вечная попытка соединения p->flag.rx_buf = 1; // прием в буфер с его автосозданием. p->flag.nagle_disabled = 1; // отмена nagle // p->time_wait_rec = tc_twrec; // по умолчанию 5 секунд // p->time_wait_cls = tc_twcls; // по умолчанию 5 секунд #if DEBUGSOO > 4 os_printf("TC: Max retry connection %d, time waits %d & %d, min heap size %d\n", p->max_conn, p->time_wait_rec, p->time_wait_cls, p->min_heap); #endif p->func_discon_cb = tc_disconnect; p->func_listen = tc_listen; p->func_sent_cb = NULL; p->func_recv = tc_recv; err = ERR_OK; } tc_servcfg = p; return err; }
//------------------------------------------------------------------------------- // TCP listen, put GET request to the server //------------------------------------------------------------------------------- err_t ICACHE_FLASH_ATTR tc_listen(TCP_SERV_CONN *ts_conn) { uint16 len = 0; uint8 *buf = NULL; struct buf_fini *p = NULL; if(iot_data_processing != NULL) { p = web_fini_init(1); // prepare empty buffer, filled with 0 if(p == NULL) return 1; tc_parse_buf(&p->ts_conn, iot_data_processing->iot_request, os_strlen(iot_data_processing->iot_request)); if(p->web_conn.webflag & SCB_USER) { // cancel send #if DEBUGSOO > 4 os_printf("iot-skip!\n"); #endif tc_close(); os_free(p); return 2; } buf = p->web_conn.msgbuf; len = p->web_conn.msgbuflen; } #if DEBUGSOO > 4 tcpsrv_print_remote_info(ts_conn); os_printf("tc_listen, send(%d): %s\n", len, buf); #endif err_t err = tcpsrv_int_sent_data(ts_conn, buf, len); os_free(p); return err; }
int main(int argc, char *argv[]) { char *dbg = NULL; #ifdef ENABLE_CRYPTO int rnd; char *ckpasswd; char *p; #endif if (argc < 2) usage(argv[0]); debug=0; setvbuf(stdout, (char*)NULL, _IONBF, 0); get_opts(argc,argv); if ( NULL == chkoptions.configfile ) { usage(argv[0]); } if (-1 == r_env_cfg(chkoptions.configfile)) usage(argv[0]); parseconfig(0); dbg = getenv("DEBUG"); if (NULL != dbg) debug = atoi(dbg); if ( 0 == chkoptions.fast ) { printf("Running lessfsck on a mounted filesystem will corrupt the databases.\n"); printf("Press ctrl-c within 5 secondes when you are not sure that the filesystem is unmounted.\n"); sleep(5); } BLKSIZE=get_blocksize(); if ( NULL != config->blockdatabs ){ printf("**************************************************\n"); printf("* Running lessfsck on a tc data store. *\n"); printf("**************************************************\n"); lessfsck_tc(); } else { printf("**************************************************\n"); printf("* Running lessfsck on a file_io data store. *\n"); printf("**************************************************\n"); lessfsck_file_io(); } printf("\nDone.\n"); clear_dirty(); tc_close(0); #ifdef ENABLE_CRYPTO if (config->encryptdata) { free(config->passwd); free(config->iv); } #endif free(config); exit(0); }
TYPED_TEST_P(TcTest, SuccessiveWrites) { const char *path = "SuccesiveWrites.dat"; char *data = (char *)getRandomBytes(16_KB); /** * open file one for actual writing * other descriptor to verify */ tc_file *tcf = tc_open(path, O_RDWR | O_CREAT, 0755); EXPECT_NOTNULL(tcf); tc_file *tcf2 = tc_open(path, O_RDONLY, 0); EXPECT_NE(tcf->fd, tcf2->fd); struct tc_iovec iov; tc_iov2file(&iov, tcf, TC_OFFSET_CUR, 4_KB, data); EXPECT_OK(tc_writev(&iov, 1, false)); tc_iov2file(&iov, tcf, TC_OFFSET_CUR, 4_KB, data + 4_KB); EXPECT_OK(tc_writev(&iov, 1, false)); char *readbuf = (char *)malloc(16_KB); tc_iov2file(&iov, tcf2, 0, 8_KB, readbuf); EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(iov.length, 8_KB); EXPECT_EQ(0, memcmp(data, readbuf, 8_KB)); tc_iov2file(&iov, tcf, TC_OFFSET_CUR, 8_KB, data + 8_KB); EXPECT_OK(tc_writev(&iov, 1, false)); tc_iov2file(&iov, tcf2, 0, 16_KB, readbuf); EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(iov.length, 16_KB); EXPECT_EQ(0, memcmp(data, readbuf, 16_KB)); tc_close(tcf); tc_close(tcf2); free(data); free(readbuf); }
TYPED_TEST_P(TcTest, SuccessiveReads) { const char *path = "TcTest-SuccesiveReads.txt"; struct tc_iovec iov; const int N = 4096; char *data; char *read; tc_file *tcf; Removev(&path, 1); data = (char *)getRandomBytes(5 * N); tc_iov4creation(&iov, path, 5 * N, data); EXPECT_OK(tc_writev(&iov, 1, false)); read = (char *)malloc(5 * N); EXPECT_NOTNULL(read); tcf = tc_open(path, O_RDONLY, 0); EXPECT_EQ(0, tc_fseek(tcf, 0, SEEK_CUR)); EXPECT_NOTNULL(tcf); tc_iov2file(&iov, tcf, TC_OFFSET_CUR, N, read); EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(N, tc_fseek(tcf, 0, SEEK_CUR)); iov.data = read + N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(2 * N, tc_fseek(tcf, 0, SEEK_CUR)); EXPECT_EQ(3 * N, tc_fseek(tcf, N, SEEK_CUR)); iov.data = read + 3 * N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(2 * N, tc_fseek(tcf, 2 * N, SEEK_SET)); iov.data = read + 2 * N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_EQ(4 * N, tc_fseek(tcf, -N, SEEK_END)); iov.data = read + 4 * N; EXPECT_OK(tc_readv(&iov, 1, false)); EXPECT_TRUE(iov.is_eof); EXPECT_EQ(0, memcmp(data, read, 5 * N)); free(data); free(read); tc_close(tcf); }
//------------------------------------------------------------------------------- // dns_found_callback //------------------------------------------------------------------------------- void ICACHE_FLASH_ATTR tc_dns_found_callback(uint8 *name, ip_addr_t *ipaddr, void *callback_arg) { #if DEBUGSOO > 4 os_printf("clb:%s, " IPSTR " ", name, IP2STR(ipaddr)); #endif if(tc_servcfg != NULL) { if(ipaddr != NULL && ipaddr->addr != 0) { tc_remote_ip = *ipaddr; err_t err = tcpsrv_client_start(tc_servcfg, tc_remote_ip.addr, DEFAULT_TC_HOST_PORT); if (err != ERR_OK) { #if DEBUGSOO > 4 os_printf("goerr=%d ", err); #endif tc_close(); } } } }
//------------------------------------------------------------------------------- // close_dns_found //------------------------------------------------------------------------------- void ICACHE_FLASH_ATTR close_dns_finding(void){ ets_timer_disarm(&error_timer); if(tc_init_flg & TC_RUNNING) { // ожидание dns_found_callback() ? // убить вызов tc_dns_found_callback() int i; for (i = 0; i < DNS_TABLE_SIZE; ++i) { if(dns_table[i].state != DNS_STATE_DONE && dns_table[i].found == (dns_found_callback)tc_dns_found_callback) { /* flush this entry */ dns_table[i].found = NULL; dns_table[i].state = DNS_STATE_UNUSED; #if DEBUGSOO > 4 os_printf("DNS unused: %s\n", dns_table[i].name); #endif } } tc_init_flg &= ~TC_RUNNING; } tc_close(); }
//------------------------------------------------------------------------------- // TCP receive response from server //------------------------------------------------------------------------------- err_t ICACHE_FLASH_ATTR tc_recv(TCP_SERV_CONN *ts_conn) { #if DEBUGSOO > 1 tcpsrv_received_data_default(ts_conn); #endif tcpsrv_unrecved_win(ts_conn); uint8 *pstr = ts_conn->pbufi; sint32 len = ts_conn->sizei; #if DEBUGSOO > 4 os_printf("IOT_Rec(%u): %s\n", len, pstr); #endif os_memset(iot_last_status, 0, sizeof(iot_last_status)); os_strncpy(iot_last_status, (char *)pstr, mMIN(sizeof(iot_last_status)-1, len)); // status/error iot_last_status_time = get_sntp_time(); if(len >= sizeof(key_http_ok1) + 3 + sizeof(key_http_ok2)) { if(os_memcmp(pstr, key_http_ok1, sizeof(key_http_ok1)-1) == 0 && os_memcmp(pstr + sizeof(key_http_ok1)-1 + 3, key_http_ok2, sizeof(key_http_ok2)-1) == 0) { // Check - 200 OK? #if DEBUGSOO > 4 os_printf(" - 200\n"); #endif uint8 *nstr = web_strnstr(pstr, "\r\n\r\n", len); // find body if(nstr != NULL) { pstr = nstr + 4; // body start len -= nstr - pstr; // body size uint8 *nstr = web_strnstr(pstr, "\r\n", len); // find next delimiter if(nstr != NULL) *nstr = '\0'; if(ahextoul(pstr)) { // not 0 = OK tc_init_flg &= ~TC_RUNNING; // clear run flag iot_data_processing->last_run = system_get_time(); #if DEBUGSOO > 4 os_printf("Ok!!!\n"); #endif } } } } //ts_conn->flag.rx_null = 1; // stop receiving data tc_close(); return ERR_OK; }
TYPED_TEST_P(TcTest, RequestDoesNotFitIntoOneCompound) { const int NFILES = 64; // 64 * 8 == 512 const char *paths[NFILES]; int flags[NFILES]; struct tc_attrs attrs[NFILES]; const char *new_paths[NFILES]; struct tc_file_pair pairs[NFILES]; const char *ROOTDIR = "DontFit"; EXPECT_TRUE(tc_rm_recursive(ROOTDIR)); for (int i = 0; i < NFILES; ++i) { paths[i] = new_auto_path("DontFit/a%03d/b/c/d/e/f/g/h/file", i); tc_ensure_parent_dir(paths[i]); flags[i] = O_WRONLY | O_CREAT; attrs[i].file = tc_file_from_path(paths[i]); new_paths[i] = new_auto_path("DontFit/file-%d", i); pairs[i].src_file = tc_file_from_path(paths[i]); pairs[i].dst_file = tc_file_from_path(new_paths[i]); } tc_file *files = tc_openv(paths, NFILES, flags, NULL); EXPECT_NOTNULL(files); EXPECT_OK(tc_closev(files, NFILES)); EXPECT_OK(tc_getattrsv(attrs, NFILES, false)); struct tc_attrs_masks listdir_mask = { .has_mode = true }; std::set<std::string> objs; EXPECT_OK(tc_listdirv(&ROOTDIR, 1, listdir_mask, 0, true, listdir_test_cb, &objs, false)); std::set<std::string> expected; for (int i = 0; i < NFILES; ++i) { std::string p(paths[i]); size_t n = p.length(); while (n != std::string::npos) { expected.emplace(p.data(), n); n = p.find_last_of('/', n - 1); } } expected.erase("DontFit"); EXPECT_THAT(objs, testing::ContainerEq(expected)); EXPECT_OK(tc_renamev(pairs, NFILES, false)); EXPECT_OK(tc_unlinkv(new_paths, NFILES)); } static bool is_same_stat(const struct stat *st1, const struct stat *st2) { return st1->st_ino == st2->st_ino && st1->st_mode == st2->st_mode && st1->st_nlink == st2->st_nlink && st1->st_uid == st2->st_uid && st1->st_gid == st2->st_gid && st1->st_rdev == st2->st_rdev && st1->st_size == st2->st_size && st1->st_mtime == st2->st_mtime && st1->st_ctime == st2->st_ctime; //&& st1->st_dev == st2->st_dev //&& st1->st_blksize == st2->st_blksize //&& st1->st_blocks == st2->st_blocks } TYPED_TEST_P(TcTest, TcStatBasics) { const char *FPATH = "TcTest-TcStatFile.txt"; const char *LPATH = "TcTest-TcStatLink.txt"; tc_unlink(FPATH); tc_unlink(LPATH); tc_touch(FPATH, 4_KB); EXPECT_EQ(0, tc_symlink(FPATH, LPATH)); struct stat st1; EXPECT_EQ(0, tc_stat(LPATH, &st1)); struct stat st2; tc_file *tcf = tc_open(FPATH, O_RDONLY, 0); EXPECT_EQ(0, tc_fstat(tcf, &st2)); EXPECT_TRUE(is_same_stat(&st1, &st2)); tc_close(tcf); struct stat st3; EXPECT_EQ(0, tc_lstat(LPATH, &st3)); EXPECT_TRUE(S_ISLNK(st3.st_mode)); EXPECT_FALSE(is_same_stat(&st1, &st3)); } TYPED_TEST_P(TcTest, TcRmBasic) { #define TCRM_PREFIX "/vfs0/tc_nfs4_test/TcRmBasic" EXPECT_OK(tc_ensure_dir(TCRM_PREFIX "/dir-a/subdir-a1", 0755, NULL)); EXPECT_OK(tc_ensure_dir(TCRM_PREFIX "/dir-a/subdir-a2", 0755, NULL)); EXPECT_OK(tc_ensure_dir(TCRM_PREFIX "/dir-b/subdir-b1", 0755, NULL)); tc_touch(TCRM_PREFIX "/dir-a/subdir-a1/a1-file1", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a1/a1-file2", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a1/a1-file3", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a2/a2-file1", 4_KB); tc_touch(TCRM_PREFIX "/dir-a/subdir-a2/a2-file2", 4_KB); tc_touch(TCRM_PREFIX "/dir-b/subdir-b1/b1-file1", 4_KB); tc_touch(TCRM_PREFIX "/dir-b/subdir-b1/b1-file2", 4_KB); tc_touch(TCRM_PREFIX "/dir-b/subdir-b1/b1-file3", 4_KB); tc_touch(TCRM_PREFIX "/file1", 4_KB); tc_touch(TCRM_PREFIX "/file2", 4_KB); const char *objs[4] = { TCRM_PREFIX "/dir-a", TCRM_PREFIX "/dir-b", TCRM_PREFIX "/file1", TCRM_PREFIX "/file2", }; EXPECT_OK(tc_rm(objs, 4, true)); #undef TCRM_PREFIX }