/***************************************************** a wrapper for pread() *******************************************************/ ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs) { struct smbw_file *file; int ret; smbw_busy++; file = smbw_file(fd); if (!file) { errno = EBADF; smbw_busy--; return -1; } ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count); if (ret == -1) { errno = smbw_errno(&file->srv->cli); smbw_busy--; return -1; } smbw_busy--; return ret; }
ssize_t SMBC_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { size_t ret; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; /* * offset: * * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- * appears to pass file->offset (which is type off_t) differently than * a local variable of type off_t. Using local variable "offset" in * the call to cli_read() instead of file->offset fixes a problem * retrieving data at an offset greater than 4GB. */ off_t offset; if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } offset = file->offset; /* Check that the buffer exists ... */ if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; } status = cli_read(file->targetcli, file->cli_fd, (char *)buf, offset, count, &ret); if (!NT_STATUS_IS_OK(status)) { errno = SMBC_errno(context, file->targetcli); TALLOC_FREE(frame); return -1; } file->offset += ret; DEBUG(4, (" --> %ld\n", (unsigned long)ret)); TALLOC_FREE(frame); return ret; /* Success, ret bytes of data ... */ }
/***************************************************** a wrapper for read() *******************************************************/ ssize_t smbw_read(int fd, void *buf, size_t count) { struct smbw_file *file; int ret; DEBUG(4,("smbw_read(%d, %d)\n", fd, (int)count)); smbw_busy++; file = smbw_file(fd); if (!file) { errno = EBADF; smbw_busy--; return -1; } ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, file->f->offset, count); if (ret == -1) { errno = smbw_errno(&file->srv->cli); smbw_busy--; return -1; } file->f->offset += ret; DEBUG(4,(" -> %d\n", ret)); smbw_busy--; return ret; }
NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx, struct cli_state *cli, const char *nt_path, const char *unix_path) { NTSTATUS result; int fnum; int fd = 0; char *data = NULL; static int io_bufsize = 64512; int read_size = io_bufsize; off_t start = 0; off_t nread = 0; if ((fnum = cli_open(cli, nt_path, O_RDONLY, DENY_NONE)) == -1) { result = NT_STATUS_NO_SUCH_FILE; goto out; } if ((fd = sys_open(unix_path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { result = map_nt_error_from_unix(errno); goto out; } if ((data = (char *)SMB_MALLOC(read_size)) == NULL) { result = NT_STATUS_NO_MEMORY; goto out; } while (1) { int n = cli_read(cli, fnum, data, nread + start, read_size); if (n <= 0) break; if (write(fd, data, n) != n) { break; } nread += n; } result = NT_STATUS_OK; out: SAFE_FREE(data); if (fnum) { cli_close(cli, fnum); } if (fd) { close(fd); } return result; }
void nb_readx(int handle, int offset, int size, int ret_size) { int i, ret; i = find_handle(handle); if ((ret=cli_read(c, ftable[i].fd, buf, offset, size)) != ret_size) { printf("(%d) ERROR: read failed on handle %d ofs=%d size=%d res=%d fd %d errno %d (%s)\n", line_count, handle, offset, size, ret, ftable[i].fd, errno, strerror(errno)); exit(1); } children[nbio_id].bytes_in += ret_size; }
void loop(int sockfd, int jsfd, const struct js_layout &layout) { struct js_event event; Bstrlib::CBString input; jsmath::js_log js(jsfd); std::array<int, 6> motors; while (js_read(jsfd, event) != -1 && !js_quit(event, layout) ) { js.update(event); js.to_motors(layout, motors); jsmath::send_motors(sockfd, motors); /* jsmath::send_motors(0, motors); */ cli_read(sockfd, input); puts(input); } }
void nb_read(int handle, int size, int offset) { int i, ret; for (i=0;i<MAX_FILES;i++) { if (ftable[i].handle == handle) break; } if (i == MAX_FILES) { printf("(%d) nb_read: handle %d was not open size=%d ofs=%d\n", line_count, handle, size, offset); return; } if ((ret=cli_read(c, ftable[i].fd, buf, offset, size)) != size) { #if NBDEBUG printf("(%d) read failed on handle %d ofs=%d size=%d res=%d\n", line_count, handle, offset, size, ret); #endif } }
void nb_readx(int handle, int offset, int size, int ret_size) { int i; NTSTATUS status; size_t nread; i = find_handle(handle); status = cli_read(c, ftable[i].fd, buf, offset, size, &nread); if (!NT_STATUS_IS_OK(status)) { printf("(%d) ERROR: read failed on handle %d ofs=%d size=%d " "fd %d nterror %s\n", line_count, handle, offset, size, ftable[i].fd, nt_errstr(status)); exit(1); } else if (nread != ret_size) { printf("(%d) ERROR: read failed on handle %d ofs=%d size=%d " "nread=%lu ret_size=%d fd %d\n", line_count, handle, offset, size, (unsigned long)nread, ret_size, ftable[i].fd); exit(1); } children[nbio_id].bytes_in += ret_size; }
ssize_t SMBC_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { size_t ret; char *server = NULL, *share = NULL, *user = NULL, *password = NULL; char *path = NULL; char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; /* * offset: * * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- * appears to pass file->offset (which is type off_t) differently than * a local variable of type off_t. Using local variable "offset" in * the call to cli_read() instead of file->offset fixes a problem * retrieving data at an offset greater than 4GB. */ off_t offset; if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } offset = file->offset; /* Check that the buffer exists ... */ if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; } /*d_printf(">>>read: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, file->fname, NULL, &server, &share, &path, &user, &password, NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } /*d_printf(">>>read: resolving %s\n", path);*/ status = cli_resolve_path(frame, "", context->internal->auth_info, file->srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path); errno = ENOENT; TALLOC_FREE(frame); return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ status = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count, &ret); if (!NT_STATUS_IS_OK(status)) { errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; } file->offset += ret; DEBUG(4, (" --> %ld\n", (unsigned long)ret)); TALLOC_FREE(frame); return ret; /* Success, ret bytes of data ... */ }
static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset) { size_t size = (size_t)cli->max_recv_frag; int stream_offset = 0; int num_read; char *pdata; int extra_data_size = ((int)*rdata_offset) + ((int)data_to_read) - (int)prs_data_size(rdata); DEBUG(5,("rpc_read: data_to_read: %u rdata offset: %u extra_data_size: %d\n", (int)data_to_read, (unsigned int)*rdata_offset, extra_data_size)); /* * Grow the buffer if needed to accommodate the data to be read. */ if (extra_data_size > 0) { if(!prs_force_grow(rdata, (uint32)extra_data_size)) { DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", extra_data_size )); return False; } DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", extra_data_size, prs_data_size(rdata) )); } pdata = prs_data_p(rdata) + *rdata_offset; do /* read data using SMBreadX */ { uint32 ecode; uint8 eclass; if (size > (size_t)data_to_read) size = (size_t)data_to_read; num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRDOS && ecode != ERRmoredata) { DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", eclass, (unsigned int)ecode)); return False; } } data_to_read -= num_read; stream_offset += num_read; pdata += num_read; } while (num_read > 0 && data_to_read > 0); /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ /* * Update the current offset into rdata by the amount read. */ *rdata_offset += stream_offset; return True; }
static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata, uint8 expected_pkt_type) { uint32 len; char *rparam = NULL; uint32 rparam_len = 0; uint16 setup[2]; BOOL first = True; BOOL last = True; RPC_HDR rhdr; char *pdata = data ? prs_data_p(data) : NULL; uint32 data_len = data ? prs_offset(data) : 0; char *prdata = NULL; uint32 rdata_len = 0; uint32 current_offset = 0; uint32 fragment_start = 0; uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024; int auth_padding_len = 0; /* Create setup parameters - must be in native byte order. */ setup[0] = TRANSACT_DCERPCCMD; setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */ DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum)); /* Send the RPC request and receive a response. For short RPC calls (about 1024 bytes or so) the RPC request and response appears in a SMBtrans request and response. Larger RPC responses are received further on. */ if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ pdata, data_len, max_data, /* data, length, max */ &rparam, &rparam_len, /* return params, len */ &prdata, &rdata_len)) /* return data, len */ { DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli))); return False; } /* Throw away returned params - we know we won't use them. */ SAFE_FREE(rparam); if (prdata == NULL) { DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n", (int)cli->nt_pipe_fnum)); return False; } /* * Give this memory as dynamically allocated to the return parse * struct. */ prs_give_memory(rdata, prdata, rdata_len, True); current_offset = rdata_len; /* This next call sets the endian bit correctly in rdata. */ if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) { prs_mem_free(rdata); return False; } if (rhdr.pkt_type == RPC_BINDACK) { if (!last && !first) { DEBUG(5,("rpc_api_pipe: bug in server (AS/U?), setting fragment first/last ON.\n")); first = True; last = True; } } if (rhdr.pkt_type == RPC_BINDNACK) { DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum)); prs_mem_free(rdata); return False; } if (rhdr.pkt_type == RPC_RESPONSE) { RPC_HDR_RESP rhdr_resp; if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) { DEBUG(5,("rpc_api_pipe: failed to unmarshal RPC_HDR_RESP.\n")); prs_mem_free(rdata); return False; } } if (rhdr.pkt_type != expected_pkt_type) { DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum, rhdr.pkt_type, expected_pkt_type)); prs_mem_free(rdata); return False; } DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n", (unsigned int)len, (unsigned int)rdata_len )); /* check if data to be sent back was too large for one SMBtrans */ /* err status is only informational: the _real_ check is on the length */ if (len > 0) { /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ /* Read the remaining part of the first response fragment */ if (!rpc_read(cli, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; } } /* * Now we have a complete PDU, check the auth struct if any was sent. */ if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) { prs_mem_free(rdata); return False; } if (rhdr.auth_len != 0) { /* * Drop the auth footers from the current offset. * We need this if there are more fragments. * The auth footers consist of the auth_data and the * preceeding 8 byte auth_header. */ current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); } /* * Only one rpc fragment, and it has been read. */ if (first && last) { DEBUG(6,("rpc_api_pipe: fragment first and last both set\n")); return True; } /* * Read more fragments using SMBreadX until we get one with the * last bit set. */ while (!last) { RPC_HDR_RESP rhdr_resp; int num_read; char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN]; prs_struct hps; uint8 eclass; uint32 ecode; /* * First read the header of the next PDU. */ prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRDOS && ecode != ERRmoredata) { DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode)); return False; } } DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); if (num_read != RPC_HEADER_LEN+RPC_HDR_RESP_LEN) { DEBUG(0,("rpc_api_pipe: Error : requested %d bytes, got %d.\n", RPC_HEADER_LEN+RPC_HDR_RESP_LEN, num_read )); return False; } /* This call sets the endianness in hps. */ if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len)) return False; /* Ensure the endianness in rdata is set correctly - must be same as hps. */ if (hps.bigendian_data != rdata->bigendian_data) { DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n", rdata->bigendian_data ? "big" : "little", hps.bigendian_data ? "big" : "little" )); return False; } if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0)) { DEBUG(0,("rpc_api_pipe: Error in unmarshalling RPC_HDR_RESP.\n")); return False; } if (first) { DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n")); return False; } /* * Now read the rest of the PDU. */ if (!rpc_read(cli, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; } fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; /* * Verify any authentication footer. */ if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) { prs_mem_free(rdata); return False; } if (rhdr.auth_len != 0 ) { /* * Drop the auth footers from the current offset. * The auth footers consist of the auth_data and the * preceeding 8 byte auth_header. * We need this if there are more fragments. */ current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); } } return True; }
static void do_atar(char *rname,char *lname,file_info *finfo1) { int fnum; SMB_BIG_UINT nread=0; char ftype; file_info2 finfo; BOOL close_done = False; BOOL shallitime=True; char data[65520]; int read_size = 65520; int datalen=0; struct timeval tp_start; GetTimeOfDay(&tp_start); ftype = '0'; /* An ordinary file ... */ if (finfo1) { finfo.size = finfo1 -> size; finfo.mode = finfo1 -> mode; finfo.uid = finfo1 -> uid; finfo.gid = finfo1 -> gid; finfo.mtime = finfo1 -> mtime; finfo.atime = finfo1 -> atime; finfo.ctime = finfo1 -> ctime; finfo.name = finfo1 -> name; } else { finfo.size = def_finfo.size; finfo.mode = def_finfo.mode; finfo.uid = def_finfo.uid; finfo.gid = def_finfo.gid; finfo.mtime = def_finfo.mtime; finfo.atime = def_finfo.atime; finfo.ctime = def_finfo.ctime; finfo.name = def_finfo.name; } if (dry_run) { DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name, (double)finfo.size)); shallitime=0; ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); ntarf++; return; } fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE); dos_clean_name(rname); if (fnum == -1) { DEBUG(0,("%s opening remote file %s (%s)\n", cli_errstr(cli),rname, cur_dir)); return; } finfo.name = string_create_s(strlen(rname)); if (finfo.name == NULL) { DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n")); return; } safe_strcpy(finfo.name,rname, strlen(rname)); if (!finfo1) { if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) { DEBUG(0, ("getattrE: %s\n", cli_errstr(cli))); return; } finfo.ctime = finfo.mtime; } DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode)); if (tar_inc && !(finfo.mode & aARCH)) { DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name)); shallitime=0; } else if (!tar_system && (finfo.mode & aSYSTEM)) { DEBUG(4, ("skipping %s - system bit is set\n", finfo.name)); shallitime=0; } else if (!tar_hidden && (finfo.mode & aHIDDEN)) { DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name)); shallitime=0; } else { DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s", finfo.name, (double)finfo.size, lname)); /* write a tar header, don't bother with mode - just set to 100644 */ writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype); while (nread < finfo.size && !close_done) { DEBUG(3,("nread=%.0f\n",(double)nread)); datalen = cli_read(cli, fnum, data, nread, read_size); if (datalen == -1) { DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli))); break; } nread += datalen; /* if file size has increased since we made file size query, truncate read so tar header for this file will be correct. */ if (nread > finfo.size) { datalen -= nread - finfo.size; DEBUG(0,("File size change - truncating %s to %.0f bytes\n", finfo.name, (double)finfo.size)); } /* add received bits of file to buffer - dotarbuf will * write out in 512 byte intervals */ if (dotarbuf(tarhandle,data,datalen) != datalen) { DEBUG(0,("Error writing to tar file - %s\n", strerror(errno))); break; } if (datalen == 0) { DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname)); break; } datalen=0; } /* pad tar file with zero's if we couldn't get entire file */ if (nread < finfo.size) { DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", (double)finfo.size, (int)nread)); if (padit(data, sizeof(data), finfo.size - nread)) DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); } /* round tar file to nearest block */ if (finfo.size % TBLOCK) dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); ntarf++; } cli_close(cli, fnum); if (shallitime) { struct timeval tp_end; int this_time; /* if shallitime is true then we didn't skip */ if (tar_reset && !dry_run) (void) do_setrattr(finfo.name, aARCH, ATTRRESET); GetTimeOfDay(&tp_end); this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000; get_total_time_ms += this_time; get_total_size += finfo.size; if (tar_noisy) { DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n", (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)), finfo.name)); } /* Thanks to Carel-Jan Engel ([email protected]) for this one */ DEBUG(3,("(%g kb/s) (average %g kb/s)\n", finfo.size / MAX(0.001, (1.024*this_time)), get_total_size / MAX(0.001, (1.024*get_total_time_ms)))); } }
bool torture_casetable(int dummy) { static struct cli_state *cli; char *fname; uint16_t fnum; int c, i; #define MAX_EQUIVALENCE 8 smb_ucs2_t equiv[0x10000][MAX_EQUIVALENCE]; printf("starting casetable\n"); if (!torture_open_connection(&cli, 0)) { return False; } memset(equiv, 0, sizeof(equiv)); cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); cli_rmdir(cli, "\\utable"); if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\utable"))) { printf("Failed to create utable directory!\n"); return False; } for (c=1; c < 0x10000; c++) { SMB_OFF_T size; if (c == '.' || c == '\\') continue; printf("%04x (%c)\n", c, isprint(c)?c:'.'); fname = form_name(c); if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum))) { printf("Failed to create file with char %04x\n", c); continue; } size = 0; if (!NT_STATUS_IS_OK(cli_qfileinfo_basic( cli, fnum, NULL, &size, NULL, NULL, NULL, NULL, NULL))) { continue; } if (size > 0) { /* found a character equivalence! */ int c2[MAX_EQUIVALENCE]; if (size/sizeof(int) >= MAX_EQUIVALENCE) { printf("too many chars match?? size=%ld c=0x%04x\n", (unsigned long)size, c); cli_close(cli, fnum); return False; } cli_read(cli, fnum, (char *)c2, 0, size); printf("%04x: ", c); equiv[c][0] = c; for (i=0; i<size/sizeof(int); i++) { printf("%04x ", c2[i]); equiv[c][i+1] = c2[i]; } printf("\n"); fflush(stdout); } cli_writeall(cli, fnum, 0, (uint8_t *)&c, size, sizeof(c), NULL); cli_close(cli, fnum); } cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); cli_rmdir(cli, "\\utable"); return True; }