Changeset 988 for vendor/current/source3/client
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source3/client
- Files:
-
- 3 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/client/client.c
r860 r988 27 27 #include "rpc_client/cli_pipe.h" 28 28 #include "client/client_proto.h" 29 #include "client/clitar_proto.h" 29 30 #include "../librpc/gen_ndr/ndr_srvsvc_c.h" 30 31 #include "../lib/util/select.h" … … 37 38 #include "trans2.h" 38 39 #include "libsmb/nmblib.h" 40 #include "include/ntioctl.h" 41 #include "../libcli/smb/smbXcli_base.h" 39 42 40 43 #ifndef REGISTER … … 45 48 46 49 extern bool override_logfile; 47 extern char tar_type;48 50 49 51 static int port = 0; 50 52 static char *service; 51 53 static char *desthost; 52 static char *calling_name;53 54 static bool grepable = false; 54 55 static char *cmdstr = NULL; 55 56 const char *cmd_ptr = NULL; 56 57 57 static int io_bufsize = 524288; 58 static int io_bufsize = 0; /* we use the default size */ 59 static int io_timeout = (CLIENT_TIMEOUT/1000); /* Per operation timeout (in seconds). */ 58 60 59 61 static int name_type = 0x20; 60 static int max_protocol = PROTOCOL_NT1;62 static int max_protocol = -1; 61 63 62 64 static int process_tok(char *tok); … … 65 67 #define CREATE_ACCESS_READ READ_CONTROL_ACCESS 66 68 67 /* 30 second timeout on most commands */68 #define CLIENT_TIMEOUT (30*1000)69 #define SHORT_TIMEOUT (5*1000)70 71 69 /* value for unused fid field in trans2 secondary request */ 72 70 #define FID_UNUSED (0xFFFF) … … 77 75 static bool translation = false; 78 76 static bool have_ip; 79 80 /* clitar bits insert */81 extern int blocksize;82 extern bool tar_inc;83 extern bool tar_reset;84 /* clitar bits end */85 77 86 78 static bool prompt = true; … … 89 81 static bool showacls = false; 90 82 bool lowercase = false; 83 static bool backup_intent = false; 91 84 92 85 static struct sockaddr_storage dest_ss; … … 234 227 235 228 i = 0; 236 while (i < (n - 1) && (i < BUFFER_SIZE)) {229 while (i < (n - 1)) { 237 230 if ((c = x_getc(f)) == EOF) { 238 231 break; … … 251 244 struct push_state { 252 245 XFILE *f; 253 SMB_OFF_Tnread;246 off_t nread; 254 247 }; 255 248 … … 306 299 static int do_dskattr(void) 307 300 { 308 int total, bsize, avail;301 uint64_t total, bsize, avail; 309 302 struct cli_state *targetcli = NULL; 310 303 char *targetpath = NULL; … … 312 305 NTSTATUS status; 313 306 314 if ( !cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(), &targetcli, &targetpath)) { 315 d_printf("Error in dskattr: %s\n", cli_errstr(cli)); 316 return 1; 317 } 318 319 status = cli_dskattr(targetcli, &bsize, &total, &avail); 307 status = cli_resolve_path(ctx, "", auth_info, cli, 308 client_get_cur_dir(), &targetcli, 309 &targetpath); 320 310 if (!NT_STATUS_IS_OK(status)) { 321 311 d_printf("Error in dskattr: %s\n", nt_errstr(status)); … … 323 313 } 324 314 325 d_printf("\n\t\t%d blocks of size %d. %d blocks available\n", 326 total, bsize, avail); 315 status = cli_disk_size(targetcli, targetpath, &bsize, &total, &avail); 316 if (!NT_STATUS_IS_OK(status)) { 317 d_printf("Error in dskattr: %s\n", nt_errstr(status)); 318 return 1; 319 } 320 321 d_printf("\n\t\t%" PRIu64 322 " blocks of size %" PRIu64 323 ". %" PRIu64 " blocks available\n", 324 total, bsize, avail); 327 325 328 326 return 0; … … 363 361 struct cli_state *targetcli = NULL; 364 362 SMB_STRUCT_STAT sbuf; 365 uint32 attributes;363 uint32_t attributes; 366 364 int ret = 1; 367 365 TALLOC_CTX *ctx = talloc_stackframe(); 366 NTSTATUS status; 368 367 369 368 newdir = talloc_strdup(ctx, new_dir); … … 407 406 client_set_cur_dir(new_cd); 408 407 409 if ( !cli_resolve_path(ctx, "", auth_info, cli, new_cd, &targetcli, &targetpath)) { 410 d_printf("cd %s: %s\n", new_cd, cli_errstr(cli)); 408 status = cli_resolve_path(ctx, "", auth_info, cli, new_cd, 409 &targetcli, &targetpath); 410 if (!NT_STATUS_IS_OK(status)) { 411 d_printf("cd %s: %s\n", new_cd, nt_errstr(status)); 411 412 client_set_cur_dir(saved_dir); 412 413 goto out; … … 421 422 Except Win9x doesn't support the qpathinfo_basic() call..... */ 422 423 423 if (targetcli->protocol > PROTOCOL_LANMAN2 && !targetcli->win95) { 424 NTSTATUS status; 424 if (smbXcli_conn_protocol(targetcli->conn) > PROTOCOL_LANMAN2 && !targetcli->win95) { 425 425 426 426 status = cli_qpathinfo_basic(targetcli, targetpath, &sbuf, … … 438 438 } 439 439 } else { 440 NTSTATUS status;441 440 442 441 targetpath = talloc_asprintf(ctx, … … 549 548 d_printf(" %-30s%7.7s %8.0f %s", 550 549 finfo->name, 551 attrib_string( finfo->mode),550 attrib_string(talloc_tos(), finfo->mode), 552 551 (double)finfo->size, 553 552 time_to_asc(t)); … … 571 570 /* print file meta date header */ 572 571 d_printf( "FILENAME:%s\n", finfo->name); 573 d_printf( "MODE:%s\n", attrib_string( finfo->mode));572 d_printf( "MODE:%s\n", attrib_string(talloc_tos(), finfo->mode)); 574 573 d_printf( "SIZE:%.0f\n", (double)finfo->size); 575 574 d_printf( "MTIME:%s", time_to_asc(t)); … … 577 576 CREATE_ACCESS_READ, 0, 578 577 FILE_SHARE_READ|FILE_SHARE_WRITE, 579 FILE_OPEN, 0x0, 0x0, &fnum );578 FILE_OPEN, 0x0, 0x0, &fnum, NULL); 580 579 if (!NT_STATUS_IS_OK(status)) { 581 580 DEBUG( 0, ("display_finfo() Failed to open %s: %s\n", … … 583 582 } else { 584 583 struct security_descriptor *sd = NULL; 585 sd = cli_query_secdesc(cli_state, fnum, ctx); 586 if (!sd) { 584 status = cli_query_secdesc(cli_state, fnum, 585 ctx, &sd); 586 if (!NT_STATUS_IS_OK(status)) { 587 587 DEBUG( 0, ("display_finfo() failed to " 588 "get security descriptor: %s", 589 cli_errstr(cli_state))); 590 status = cli_nt_error(cli_state); 588 "get security descriptor: %s", 589 nt_errstr(status))); 591 590 } else { 592 591 display_sec_desc(sd); … … 704 703 } 705 704 if (do_list_queue) { 706 s afe_strcpy_base(do_list_queue + do_list_queue_end,705 strlcpy_base(do_list_queue + do_list_queue_end, 707 706 entry, do_list_queue, do_list_queue_size); 708 707 do_list_queue_end = new_end; … … 815 814 816 815 NTSTATUS do_list(const char *mask, 817 uint16 attribute,816 uint16_t attribute, 818 817 NTSTATUS (*fn)(struct cli_state *cli_state, struct file_info *, 819 818 const char *dir), … … 859 858 /* check for dfs */ 860 859 861 if ( !cli_resolve_path(ctx, "", auth_info, cli, head, &targetcli, &targetpath ) ) { 862 d_printf("do_list: [%s] %s\n", head, cli_errstr(cli)); 860 status = cli_resolve_path(ctx, "", auth_info, cli, 861 head, &targetcli, 862 &targetpath); 863 if (!NT_STATUS_IS_OK(status)) { 864 d_printf("do_list: [%s] %s\n", head, 865 nt_errstr(status)); 863 866 remove_do_list_queue_head(); 864 867 continue; … … 898 901 } else { 899 902 /* check for dfs */ 900 if (cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetpath)) { 901 903 status = cli_resolve_path(ctx, "", auth_info, cli, mask, 904 &targetcli, &targetpath); 905 if (NT_STATUS_IS_OK(status)) { 902 906 status = cli_list(targetcli, targetpath, attribute, 903 907 do_list_helper, targetcli); … … 909 913 TALLOC_FREE(targetpath); 910 914 } else { 911 d_printf("do_list: [%s] %s\n", mask, cli_errstr(cli));912 ret_status = cli_nt_error(cli);915 d_printf("do_list: [%s] %s\n", mask, nt_errstr(status)); 916 ret_status = status; 913 917 } 914 918 } … … 926 930 { 927 931 TALLOC_CTX *ctx = talloc_tos(); 928 uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;932 uint16_t attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; 929 933 char *mask = NULL; 930 934 char *buf = NULL; … … 976 980 { 977 981 TALLOC_CTX *ctx = talloc_tos(); 978 uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;982 uint16_t attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; 979 983 char *mask = NULL; 980 984 char *buf = NULL; … … 1060 1064 bool newhandle = false; 1061 1065 struct timespec tp_start; 1062 uint16 attr;1063 SMB_OFF_Tsize;1066 uint16_t attr; 1067 off_t size; 1064 1068 off_t start = 0; 1065 SMB_OFF_Tnread = 0;1069 off_t nread = 0; 1066 1070 int rc = 0; 1067 1071 struct cli_state *targetcli = NULL; … … 1076 1080 1077 1081 if (lowercase) { 1078 strlower_m(lname); 1079 } 1080 1081 if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname ) ) { 1082 d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli)); 1082 if (!strlower_m(lname)) { 1083 d_printf("strlower_m %s failed\n", lname); 1084 return 1; 1085 } 1086 } 1087 1088 status = cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, 1089 &targetname); 1090 if (!NT_STATUS_IS_OK(status)) { 1091 d_printf("Failed to open %s: %s\n", rname, nt_errstr(status)); 1083 1092 return 1; 1084 1093 } … … 1097 1106 } else { 1098 1107 if (reget) { 1099 handle = sys_open(lname, O_WRONLY|O_CREAT, 0644);1108 handle = open(lname, O_WRONLY|O_CREAT, 0644); 1100 1109 if (handle >= 0) { 1101 start = sys_lseek(handle, 0, SEEK_END);1110 start = lseek(handle, 0, SEEK_END); 1102 1111 if (start == -1) { 1103 1112 d_printf("Error seeking local file\n"); … … 1106 1115 } 1107 1116 } else { 1108 handle = sys_open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644);1117 handle = open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644); 1109 1118 } 1110 1119 newhandle = true; … … 1150 1159 1151 1160 if (archive_level >= 2 && (attr & FILE_ATTRIBUTE_ARCHIVE)) { 1152 cli_setatr(cli, rname, attr & ~(uint16 )FILE_ATTRIBUTE_ARCHIVE, 0);1161 cli_setatr(cli, rname, attr & ~(uint16_t)FILE_ATTRIBUTE_ARCHIVE, 0); 1153 1162 } 1154 1163 … … 1284 1293 string_replace(finfo->name,'\\','/'); 1285 1294 if (lowercase) { 1286 strlower_m(finfo->name); 1295 if (!strlower_m(finfo->name)) { 1296 return NT_STATUS_INVALID_PARAMETER; 1297 } 1287 1298 } 1288 1299 … … 1348 1359 int fd; 1349 1360 int rc = 0; 1361 mode_t mask; 1350 1362 1351 1363 rname = talloc_strdup(ctx, client_get_cur_dir()); … … 1358 1370 return 1; 1359 1371 } 1372 mask = umask(S_IRWXO | S_IRWXG); 1360 1373 fd = mkstemp(lname); 1374 umask(mask); 1361 1375 if (fd == -1) { 1362 1376 d_printf("failed to create temporary file for more\n"); … … 1406 1420 { 1407 1421 TALLOC_CTX *ctx = talloc_tos(); 1408 uint16 attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;1422 uint16_t attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; 1409 1423 char *mget_mask = NULL; 1410 1424 char *buf = NULL; … … 1470 1484 NTSTATUS status; 1471 1485 1472 if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) { 1473 d_printf("mkdir %s: %s\n", name, cli_errstr(cli)); 1486 status = cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, 1487 &targetname); 1488 if (!NT_STATUS_IS_OK(status)) { 1489 d_printf("mkdir %s: %s\n", name, nt_errstr(status)); 1474 1490 return false; 1475 1491 } … … 1526 1542 char *mask = NULL; 1527 1543 char *buf = NULL; 1544 NTSTATUS status; 1528 1545 1529 1546 mask = talloc_strdup(ctx, client_get_cur_dir()); … … 1556 1573 } 1557 1574 1558 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 1575 status = cli_resolve_path(ctx, "", auth_info, cli, mask, 1576 &targetcli, &targetname); 1577 if (!NT_STATUS_IS_OK(status)) { 1559 1578 return 1; 1560 1579 } … … 1616 1635 static char *attr_str(TALLOC_CTX *mem_ctx, uint16_t mode) 1617 1636 { 1618 char *attrs = TALLOC_ZERO_ARRAY(mem_ctx, char, 17);1637 char *attrs = talloc_zero_array(mem_ctx, char, 17); 1619 1638 int i = 0; 1620 1639 … … 1671 1690 fstring altname; 1672 1691 struct timespec b_time, a_time, m_time, c_time; 1673 SMB_OFF_Tsize;1692 off_t size; 1674 1693 uint16_t mode; 1675 SMB_INO_T ino;1676 1694 NTTIME tmp; 1677 1695 uint16_t fnum; … … 1687 1705 d_printf("%s getting alt name for %s\n", nt_errstr(status), 1688 1706 name); 1689 return false; 1707 /* 1708 * Ignore not supported or not implemented, it does not 1709 * hurt if we can't list alternate names. 1710 */ 1711 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED) || 1712 NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { 1713 altname[0] = '\0'; 1714 } else { 1715 return false; 1716 } 1690 1717 } 1691 1718 d_printf("altname: %s\n", altname); 1692 1719 1693 status = cli_qpathinfo 2(cli, name, &b_time, &a_time, &m_time, &c_time,1694 &size, &mode, &ino);1720 status = cli_qpathinfo3(cli, name, &b_time, &a_time, &m_time, &c_time, 1721 &size, &mode, NULL); 1695 1722 if (!NT_STATUS_IS_OK(status)) { 1696 1723 d_printf("%s getting pathinfo for %s\n", nt_errstr(status), … … 1699 1726 } 1700 1727 1701 unix_timespec_to_nt_time(&tmp,b_time);1728 tmp = unix_timespec_to_nt_time(b_time); 1702 1729 d_printf("create_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1703 1730 1704 unix_timespec_to_nt_time(&tmp,a_time);1731 tmp = unix_timespec_to_nt_time(a_time); 1705 1732 d_printf("access_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1706 1733 1707 unix_timespec_to_nt_time(&tmp,m_time);1734 tmp = unix_timespec_to_nt_time(m_time); 1708 1735 d_printf("write_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1709 1736 1710 unix_timespec_to_nt_time(&tmp,c_time);1737 tmp = unix_timespec_to_nt_time(c_time); 1711 1738 d_printf("change_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1712 1739 … … 1724 1751 d_printf("stream: [%s], %lld bytes\n", streams[i].name, 1725 1752 (unsigned long long)streams[i].size); 1753 } 1754 1755 if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { 1756 char *subst, *print; 1757 uint32_t flags; 1758 1759 status = cli_readlink(cli, name, talloc_tos(), &subst, &print, 1760 &flags); 1761 if (!NT_STATUS_IS_OK(status)) { 1762 d_fprintf(stderr, "cli_readlink returned %s\n", 1763 nt_errstr(status)); 1764 } else { 1765 d_printf("symlink: subst=[%s], print=[%s], flags=%x\n", 1766 subst, print, flags); 1767 TALLOC_FREE(subst); 1768 TALLOC_FREE(print); 1769 } 1726 1770 } 1727 1771 … … 1731 1775 FILE_SHARE_READ|FILE_SHARE_WRITE 1732 1776 |FILE_SHARE_DELETE, 1733 FILE_OPEN, 0x0, 0x0, &fnum );1777 FILE_OPEN, 0x0, 0x0, &fnum, NULL); 1734 1778 if (!NT_STATUS_IS_OK(status)) { 1735 1779 /* … … 1752 1796 snap_name = talloc_asprintf(talloc_tos(), "%s%s", 1753 1797 snapshots[i], name); 1754 status = cli_qpathinfo 2(cli, snap_name, &b_time, &a_time,1798 status = cli_qpathinfo3(cli, snap_name, &b_time, &a_time, 1755 1799 &m_time, &c_time, &size, 1756 1800 NULL, NULL); … … 1761 1805 continue; 1762 1806 } 1763 unix_timespec_to_nt_time(&tmp,b_time);1807 tmp = unix_timespec_to_nt_time(b_time); 1764 1808 d_printf("create_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1765 unix_timespec_to_nt_time(&tmp,a_time);1809 tmp = unix_timespec_to_nt_time(a_time); 1766 1810 d_printf("access_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1767 unix_timespec_to_nt_time(&tmp,m_time);1811 tmp =unix_timespec_to_nt_time(m_time); 1768 1812 d_printf("write_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1769 unix_timespec_to_nt_time(&tmp,c_time);1813 tmp = unix_timespec_to_nt_time(c_time); 1770 1814 d_printf("change_time: %s\n", nt_time_string(talloc_tos(), tmp)); 1771 1815 d_printf("size: %d\n", (int)size); … … 1773 1817 1774 1818 TALLOC_FREE(snapshots); 1819 cli_close(cli, fnum); 1775 1820 1776 1821 return 0; … … 1815 1860 uint16_t fnum; 1816 1861 XFILE *f; 1817 SMB_OFF_Tstart = 0;1862 off_t start = 0; 1818 1863 int rc = 0; 1819 1864 struct timespec tp_start; … … 1823 1868 NTSTATUS status; 1824 1869 1825 if (!cli_resolve_path(ctx, "", auth_info, cli, rname, &targetcli, &targetname)) { 1826 d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli)); 1870 status = cli_resolve_path(ctx, "", auth_info, cli, rname, 1871 &targetcli, &targetname); 1872 if (!NT_STATUS_IS_OK(status)) { 1873 d_printf("Failed to open %s: %s\n", rname, nt_errstr(status)); 1827 1874 return 1; 1828 1875 } … … 2049 2096 const char *expression, bool match) 2050 2097 { 2051 SMB_STRUCT_DIR *dir;2098 DIR *dir; 2052 2099 struct file_list *entry; 2053 2100 struct stat statbuf; … … 2057 2104 const char *dname; 2058 2105 2059 dir = sys_opendir(directory);2106 dir = opendir(directory); 2060 2107 if (!dir) 2061 2108 return -1; … … 2086 2133 if (ret == -1) { 2087 2134 SAFE_FREE(path); 2088 sys_closedir(dir);2135 closedir(dir); 2089 2136 return -1; 2090 2137 } … … 2093 2140 if (!entry) { 2094 2141 d_printf("Out of memory in file_find\n"); 2095 sys_closedir(dir);2142 closedir(dir); 2096 2143 return -1; 2097 2144 } … … 2104 2151 } 2105 2152 2106 sys_closedir(dir);2153 closedir(dir); 2107 2154 return 0; 2108 2155 } … … 2213 2260 return 0; 2214 2261 } else { 2215 d_printf("Error cancelling job %d : %s\n",job,cli_errstr(cli)); 2262 NTSTATUS status = cli_nt_error(cli); 2263 d_printf("Error cancelling job %d : %s\n", 2264 job, nt_errstr(status)); 2216 2265 return 1; 2217 2266 } … … 2265 2314 "%s-%d", 2266 2315 p+1, 2267 (int) sys_getpid());2316 (int)getpid()); 2268 2317 } 2269 2318 if (strequal(lname,"-")) { 2270 2319 rname = talloc_asprintf(ctx, 2271 2320 "stdin-%d", 2272 (int) sys_getpid());2321 (int)getpid()); 2273 2322 } 2274 2323 if (!rname) { … … 2342 2391 char *buf = NULL; 2343 2392 NTSTATUS status = NT_STATUS_OK; 2344 uint16 attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;2393 uint16_t attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; 2345 2394 2346 2395 if (recurse) { … … 2377 2426 char *mask = NULL; 2378 2427 char *buf = NULL; 2379 uint16 attribute;2428 uint16_t attribute; 2380 2429 struct cli_state *targetcli; 2381 2430 char *targetname = NULL; … … 2387 2436 } 2388 2437 2389 attribute = (uint16 )strtol(buf, (char **)NULL, 16);2438 attribute = (uint16_t)strtol(buf, (char **)NULL, 16); 2390 2439 2391 2440 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2401 2450 } 2402 2451 2403 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 2404 d_printf("cmd_wdel %s: %s\n", mask, cli_errstr(cli)); 2452 status = cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, 2453 &targetname); 2454 if (!NT_STATUS_IS_OK(status)) { 2455 d_printf("cmd_wdel %s: %s\n", mask, nt_errstr(status)); 2405 2456 return 1; 2406 2457 } … … 2425 2476 struct cli_state *targetcli; 2426 2477 uint16_t fnum = (uint16_t)-1; 2478 NTSTATUS status; 2427 2479 2428 2480 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2438 2490 } 2439 2491 2440 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 2441 d_printf("open %s: %s\n", mask, cli_errstr(cli)); 2442 return 1; 2443 } 2444 2445 if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetname, 0, 2492 status = cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, 2493 &targetname); 2494 if (!NT_STATUS_IS_OK(status)) { 2495 d_printf("open %s: %s\n", mask, nt_errstr(status)); 2496 return 1; 2497 } 2498 2499 status = cli_ntcreate(targetcli, targetname, 0, 2446 2500 FILE_READ_DATA|FILE_WRITE_DATA, 0, 2447 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) { 2448 if (NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetname, 0, 2501 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 2502 0x0, 0x0, &fnum, NULL); 2503 if (!NT_STATUS_IS_OK(status)) { 2504 status = cli_ntcreate(targetcli, targetname, 0, 2449 2505 FILE_READ_DATA, 0, 2450 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) { 2506 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 2507 0x0, 0x0, &fnum, NULL); 2508 if (NT_STATUS_IS_OK(status)) { 2451 2509 d_printf("open file %s: for read/write fnum %d\n", targetname, fnum); 2452 2510 } else { 2453 d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli)); 2511 d_printf("Failed to open file %s. %s\n", 2512 targetname, nt_errstr(status)); 2454 2513 } 2455 2514 } else { … … 2514 2573 mode_t mode; 2515 2574 uint16_t fnum; 2575 NTSTATUS status; 2516 2576 2517 2577 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2533 2593 mode = (mode_t)strtol(buf, (char **)NULL, 8); 2534 2594 2535 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 2536 d_printf("posix_open %s: %s\n", mask, cli_errstr(cli)); 2537 return 1; 2538 } 2539 2540 if (!NT_STATUS_IS_OK(cli_posix_open(targetcli, targetname, O_CREAT|O_RDWR, mode, &fnum))) { 2541 if (NT_STATUS_IS_OK(cli_posix_open(targetcli, targetname, O_CREAT|O_RDONLY, mode, &fnum))) { 2542 d_printf("posix_open file %s: for readonly fnum %d\n", targetname, fnum); 2595 status = cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, 2596 &targetname); 2597 if (!NT_STATUS_IS_OK(status)) { 2598 d_printf("posix_open %s: %s\n", mask, nt_errstr(status)); 2599 return 1; 2600 } 2601 2602 status = cli_posix_open(targetcli, targetname, O_CREAT|O_RDWR, mode, 2603 &fnum); 2604 if (!NT_STATUS_IS_OK(status)) { 2605 status = cli_posix_open(targetcli, targetname, 2606 O_CREAT|O_RDONLY, mode, &fnum); 2607 if (!NT_STATUS_IS_OK(status)) { 2608 d_printf("Failed to open file %s. %s\n", targetname, 2609 nt_errstr(status)); 2543 2610 } else { 2544 d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli)); 2611 d_printf("posix_open file %s: for readonly fnum %d\n", 2612 targetname, fnum); 2545 2613 } 2546 2614 } else { 2547 d_printf("posix_open file %s: for read/write fnum %d\n", targetname, fnum); 2615 d_printf("posix_open file %s: for read/write fnum %d\n", 2616 targetname, fnum); 2548 2617 } 2549 2618 … … 2559 2628 struct cli_state *targetcli; 2560 2629 mode_t mode; 2630 NTSTATUS status; 2561 2631 2562 2632 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2578 2648 mode = (mode_t)strtol(buf, (char **)NULL, 8); 2579 2649 2580 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 2581 d_printf("posix_mkdir %s: %s\n", mask, cli_errstr(cli)); 2582 return 1; 2583 } 2584 2585 if (!NT_STATUS_IS_OK(cli_posix_mkdir(targetcli, targetname, mode))) { 2586 d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli)); 2650 status = cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, 2651 &targetname); 2652 if (!NT_STATUS_IS_OK(status)) { 2653 d_printf("posix_mkdir %s: %s\n", mask, nt_errstr(status)); 2654 return 1; 2655 } 2656 2657 status = cli_posix_mkdir(targetcli, targetname, mode); 2658 if (!NT_STATUS_IS_OK(status)) { 2659 d_printf("Failed to open file %s. %s\n", 2660 targetname, nt_errstr(status)); 2587 2661 } else { 2588 2662 d_printf("posix_mkdir created directory %s\n", targetname); … … 2598 2672 char *targetname = NULL; 2599 2673 struct cli_state *targetcli; 2674 NTSTATUS status; 2600 2675 2601 2676 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2611 2686 } 2612 2687 2613 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 2614 d_printf("posix_unlink %s: %s\n", mask, cli_errstr(cli)); 2615 return 1; 2616 } 2617 2618 if (!NT_STATUS_IS_OK(cli_posix_unlink(targetcli, targetname))) { 2619 d_printf("Failed to unlink file %s. %s\n", targetname, cli_errstr(cli)); 2688 status = cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, 2689 &targetname); 2690 if (!NT_STATUS_IS_OK(status)) { 2691 d_printf("posix_unlink %s: %s\n", mask, nt_errstr(status)); 2692 return 1; 2693 } 2694 2695 status = cli_posix_unlink(targetcli, targetname); 2696 if (!NT_STATUS_IS_OK(status)) { 2697 d_printf("Failed to unlink file %s. %s\n", 2698 targetname, nt_errstr(status)); 2620 2699 } else { 2621 2700 d_printf("posix_unlink deleted file %s\n", targetname); … … 2632 2711 char *targetname = NULL; 2633 2712 struct cli_state *targetcli; 2713 NTSTATUS status; 2634 2714 2635 2715 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2645 2725 } 2646 2726 2647 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 2648 d_printf("posix_rmdir %s: %s\n", mask, cli_errstr(cli)); 2649 return 1; 2650 } 2651 2652 if (!NT_STATUS_IS_OK(cli_posix_rmdir(targetcli, targetname))) { 2653 d_printf("Failed to unlink directory %s. %s\n", targetname, cli_errstr(cli)); 2727 status = cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, 2728 &targetname); 2729 if (!NT_STATUS_IS_OK(status)) { 2730 d_printf("posix_rmdir %s: %s\n", mask, nt_errstr(status)); 2731 return 1; 2732 } 2733 2734 status = cli_posix_rmdir(targetcli, targetname); 2735 if (!NT_STATUS_IS_OK(status)) { 2736 d_printf("Failed to unlink directory %s. %s\n", 2737 targetname, nt_errstr(status)); 2654 2738 } else { 2655 2739 d_printf("posix_rmdir deleted directory %s\n", targetname); … … 2664 2748 char *buf = NULL; 2665 2749 int fnum; 2750 NTSTATUS status; 2666 2751 2667 2752 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2672 2757 fnum = atoi(buf); 2673 2758 /* We really should use the targetcli here.... */ 2674 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) { 2675 d_printf("close %d: %s\n", fnum, cli_errstr(cli)); 2759 status = cli_close(cli, fnum); 2760 if (!NT_STATUS_IS_OK(status)) { 2761 d_printf("close %d: %s\n", fnum, nt_errstr(status)); 2676 2762 return 1; 2677 2763 } … … 2682 2768 { 2683 2769 TALLOC_CTX *ctx = talloc_tos(); 2684 uint16 major, minor;2685 uint32 caplow, caphigh;2770 uint16_t major, minor; 2771 uint32_t caplow, caphigh; 2686 2772 char *caps; 2687 2773 NTSTATUS status; … … 2791 2877 enum brl_type lock_type; 2792 2878 int fnum; 2879 NTSTATUS status; 2793 2880 2794 2881 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2826 2913 len = (uint64_t)strtol(buf, (char **)NULL, 16); 2827 2914 2828 if (!NT_STATUS_IS_OK(cli_posix_lock(cli, fnum, start, len, true, lock_type))) { 2829 d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli)); 2915 status = cli_posix_lock(cli, fnum, start, len, true, lock_type); 2916 if (!NT_STATUS_IS_OK(status)) { 2917 d_printf("lock failed %d: %s\n", fnum, nt_errstr(status)); 2830 2918 } 2831 2919 … … 2839 2927 uint64_t start, len; 2840 2928 int fnum; 2929 NTSTATUS status; 2841 2930 2842 2931 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2860 2949 len = (uint64_t)strtol(buf, (char **)NULL, 16); 2861 2950 2862 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli, fnum, start, len))) { 2863 d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli)); 2951 status = cli_posix_unlock(cli, fnum, start, len); 2952 if (!NT_STATUS_IS_OK(status)) { 2953 d_printf("unlock failed %d: %s\n", fnum, nt_errstr(status)); 2864 2954 } 2865 2955 … … 2879 2969 char *targetname = NULL; 2880 2970 struct cli_state *targetcli; 2971 NTSTATUS status; 2881 2972 2882 2973 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2892 2983 } 2893 2984 2894 if (!cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetname)) { 2895 d_printf("rmdir %s: %s\n", mask, cli_errstr(cli)); 2896 return 1; 2897 } 2898 2899 if (!NT_STATUS_IS_OK(cli_rmdir(targetcli, targetname))) { 2985 status = cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, 2986 &targetname); 2987 if (!NT_STATUS_IS_OK(status)) { 2988 d_printf("rmdir %s: %s\n", mask, nt_errstr(status)); 2989 return 1; 2990 } 2991 2992 status = cli_rmdir(targetcli, targetname); 2993 if (!NT_STATUS_IS_OK(status)) { 2900 2994 d_printf("%s removing remote directory file %s\n", 2901 cli_errstr(targetcli),mask);2995 nt_errstr(status), mask); 2902 2996 } 2903 2997 … … 2918 3012 char *targetname = NULL; 2919 3013 struct cli_state *targetcli; 3014 NTSTATUS status; 2920 3015 2921 3016 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || … … 2939 3034 } 2940 3035 2941 if (!cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, &targetname)) { 2942 d_printf("link %s: %s\n", oldname, cli_errstr(cli)); 3036 status = cli_resolve_path(ctx, "", auth_info, cli, oldname, &targetcli, 3037 &targetname); 3038 if (!NT_STATUS_IS_OK(status)) { 3039 d_printf("link %s: %s\n", oldname, nt_errstr(status)); 2943 3040 return 1; 2944 3041 } … … 2949 3046 } 2950 3047 2951 if (!NT_STATUS_IS_OK(cli_posix_hardlink(targetcli, targetname, newname))) { 2952 d_printf("%s linking files (%s -> %s)\n", cli_errstr(targetcli), newname, oldname); 3048 status = cli_posix_hardlink(targetcli, targetname, newname); 3049 if (!NT_STATUS_IS_OK(status)) { 3050 d_printf("%s linking files (%s -> %s)\n", 3051 nt_errstr(status), newname, oldname); 2953 3052 return 1; 2954 3053 } … … 2968 3067 char linkname[PATH_MAX+1]; 2969 3068 struct cli_state *targetcli; 3069 NTSTATUS status; 2970 3070 2971 3071 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { … … 2981 3081 } 2982 3082 2983 if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) { 2984 d_printf("readlink %s: %s\n", name, cli_errstr(cli)); 3083 status = cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, 3084 &targetname); 3085 if (!NT_STATUS_IS_OK(status)) { 3086 d_printf("readlink %s: %s\n", name, nt_errstr(status)); 2985 3087 return 1; 2986 3088 } … … 2991 3093 } 2992 3094 2993 if (!NT_STATUS_IS_OK(cli_posix_readlink(targetcli, name,2994 linkname, PATH_MAX+1))) {3095 status = cli_posix_readlink(targetcli, name, linkname, PATH_MAX+1); 3096 if (!NT_STATUS_IS_OK(status)) { 2995 3097 d_printf("%s readlink on file %s\n", 2996 cli_errstr(targetcli), name);3098 nt_errstr(status), name); 2997 3099 return 1; 2998 3100 } … … 3016 3118 char *buf2 = NULL; 3017 3119 struct cli_state *newcli; 3120 NTSTATUS status; 3018 3121 3019 3122 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || … … 3025 3128 oldname = buf; 3026 3129 3027 newname = talloc_asprintf(ctx, 3028 "%s%s", 3029 client_get_cur_dir(), 3030 buf2); 3031 if (!newname) { 3032 return 1; 3033 } 3034 3035 /* New name must be present in share namespace. */ 3036 if (!cli_resolve_path(ctx, "", auth_info, cli, newname, &newcli, &newname)) { 3037 d_printf("link %s: %s\n", oldname, cli_errstr(cli)); 3038 return 1; 3039 } 3040 3041 if (!SERVER_HAS_UNIX_CIFS(newcli)) { 3042 d_printf("Server doesn't support UNIX CIFS calls.\n"); 3043 return 1; 3044 } 3045 3046 if (!NT_STATUS_IS_OK(cli_posix_symlink(newcli, oldname, newname))) { 3130 if (SERVER_HAS_UNIX_CIFS(cli)) { 3131 newname = talloc_asprintf(ctx, "%s%s", client_get_cur_dir(), 3132 buf2); 3133 if (!newname) { 3134 return 1; 3135 } 3136 /* New name must be present in share namespace. */ 3137 status = cli_resolve_path(ctx, "", auth_info, cli, newname, 3138 &newcli, &newname); 3139 if (!NT_STATUS_IS_OK(status)) { 3140 d_printf("link %s: %s\n", oldname, nt_errstr(status)); 3141 return 1; 3142 } 3143 status = cli_posix_symlink(newcli, oldname, newname); 3144 } else { 3145 status = cli_symlink( 3146 cli, oldname, buf2, 3147 buf2[0] == '\\' ? 0 : SYMLINK_FLAG_RELATIVE); 3148 } 3149 3150 if (!NT_STATUS_IS_OK(status)) { 3047 3151 d_printf("%s symlinking files (%s -> %s)\n", 3048 cli_errstr(newcli), newname, newname);3152 nt_errstr(status), oldname, newname); 3049 3153 return 1; 3050 3154 } … … 3066 3170 struct cli_state *targetcli; 3067 3171 mode_t mode; 3172 NTSTATUS status; 3068 3173 3069 3174 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || … … 3082 3187 mode = (mode_t)strtol(buf, NULL, 8); 3083 3188 3084 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { 3085 d_printf("chmod %s: %s\n", src, cli_errstr(cli)); 3189 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3190 &targetname); 3191 if (!NT_STATUS_IS_OK(status)) { 3192 d_printf("chmod %s: %s\n", src, nt_errstr(status)); 3086 3193 return 1; 3087 3194 } … … 3092 3199 } 3093 3200 3094 if (!NT_STATUS_IS_OK(cli_posix_chmod(targetcli, targetname, mode))) { 3201 status = cli_posix_chmod(targetcli, targetname, mode); 3202 if (!NT_STATUS_IS_OK(status)) { 3095 3203 d_printf("%s chmod file %s 0%o\n", 3096 cli_errstr(targetcli), src, (unsigned int)mode);3204 nt_errstr(status), src, (unsigned int)mode); 3097 3205 return 1; 3098 3206 } … … 3214 3322 char *targetname = NULL; 3215 3323 struct cli_state *targetcli; 3216 uint16 major, minor;3217 uint32 caplow, caphigh;3324 uint16_t major, minor; 3325 uint32_t caplow, caphigh; 3218 3326 char *retbuf = NULL; 3219 3327 size_t rb_size = 0; 3220 3328 SMB_STRUCT_STAT sbuf; 3221 uint16 num_file_acls = 0;3222 uint16 num_dir_acls = 0;3223 uint16 i;3329 uint16_t num_file_acls = 0; 3330 uint16_t num_dir_acls = 0; 3331 uint16_t i; 3224 3332 NTSTATUS status; 3225 3333 … … 3236 3344 } 3237 3345 3238 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { 3239 d_printf("stat %s: %s\n", src, cli_errstr(cli)); 3346 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3347 &targetname); 3348 if (!NT_STATUS_IS_OK(status)) { 3349 d_printf("stat %s: %s\n", src, nt_errstr(status)); 3240 3350 return 1; 3241 3351 } … … 3260 3370 } 3261 3371 3372 status = cli_posix_stat(targetcli, targetname, &sbuf); 3262 3373 if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) { 3263 3374 d_printf("%s getfacl doing a stat on file %s\n", 3264 cli_errstr(targetcli), src); 3265 return 1; 3266 } 3267 3268 if (!NT_STATUS_IS_OK(cli_posix_getfacl(targetcli, targetname, ctx, &rb_size, &retbuf))) { 3375 nt_errstr(status), src); 3376 return 1; 3377 } 3378 3379 status = cli_posix_getacl(targetcli, targetname, ctx, &rb_size, &retbuf); 3380 if (!NT_STATUS_IS_OK(status)) { 3269 3381 d_printf("%s getfacl file %s\n", 3270 cli_errstr(targetcli), src);3382 nt_errstr(status), src); 3271 3383 return 1; 3272 3384 } … … 3297 3409 3298 3410 for (i = 0; i < num_file_acls; i++) { 3299 uint32 uorg;3411 uint32_t uorg; 3300 3412 fstring permstring; 3301 3413 unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)); … … 3334 3446 3335 3447 for (i = 0; i < num_dir_acls; i++) { 3336 uint32 uorg;3448 uint32_t uorg; 3337 3449 fstring permstring; 3338 3450 unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)); … … 3373 3485 } 3374 3486 3375 static void printf_cb(const char *buf, void *private_data)3376 {3377 printf("%s", buf);3378 }3379 3380 3487 /**************************************************************************** 3381 3488 Get the EA list of a file … … 3405 3512 } 3406 3513 3407 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3408 &targetname)) { 3409 d_printf("stat %s: %s\n", src, cli_errstr(cli)); 3514 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3515 &targetname); 3516 if (!NT_STATUS_IS_OK(status)) { 3517 d_printf("stat %s: %s\n", src, nt_errstr(status)); 3410 3518 return 1; 3411 3519 } … … 3420 3528 for (i=0; i<num_eas; i++) { 3421 3529 d_printf("%s (%d) =\n", eas[i].name, (int)eas[i].flags); 3422 dump_data_ cb(eas[i].value.data, eas[i].value.length, false,3423 printf_cb, NULL);3530 dump_data_file(eas[i].value.data, eas[i].value.length, false, 3531 stdout); 3424 3532 d_printf("\n"); 3425 3533 } … … 3461 3569 } 3462 3570 3463 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3464 &targetname)) { 3465 d_printf("stat %s: %s\n", src, cli_errstr(cli)); 3571 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3572 &targetname); 3573 if (!NT_STATUS_IS_OK(status)) { 3574 d_printf("stat %s: %s\n", src, nt_errstr(status)); 3466 3575 return 1; 3467 3576 } … … 3492 3601 struct tm *lt; 3493 3602 time_t tmp_time; 3603 NTSTATUS status; 3494 3604 3495 3605 if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) { … … 3505 3615 } 3506 3616 3507 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { 3508 d_printf("stat %s: %s\n", src, cli_errstr(cli)); 3617 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3618 &targetname); 3619 if (!NT_STATUS_IS_OK(status)) { 3620 d_printf("stat %s: %s\n", src, nt_errstr(status)); 3509 3621 return 1; 3510 3622 } … … 3515 3627 } 3516 3628 3517 if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) { 3629 status = cli_posix_stat(targetcli, targetname, &sbuf); 3630 if (!NT_STATUS_IS_OK(status)) { 3518 3631 d_printf("%s stat file %s\n", 3519 cli_errstr(targetcli), src);3632 nt_errstr(status), src); 3520 3633 return 1; 3521 3634 } … … 3591 3704 struct cli_state *targetcli; 3592 3705 char *targetname = NULL; 3706 NTSTATUS status; 3593 3707 3594 3708 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || … … 3609 3723 return 1; 3610 3724 } 3611 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname) ) { 3612 d_printf("chown %s: %s\n", src, cli_errstr(cli)); 3725 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3726 &targetname); 3727 if (!NT_STATUS_IS_OK(status)) { 3728 d_printf("chown %s: %s\n", src, nt_errstr(status)); 3613 3729 return 1; 3614 3730 } … … 3619 3735 } 3620 3736 3621 if (!NT_STATUS_IS_OK(cli_posix_chown(targetcli, targetname, uid, gid))) { 3737 status = cli_posix_chown(targetcli, targetname, uid, gid); 3738 if (!NT_STATUS_IS_OK(status)) { 3622 3739 d_printf("%s chown file %s uid=%d, gid=%d\n", 3623 cli_errstr(targetcli), src, (int)uid, (int)gid);3740 nt_errstr(status), src, (int)uid, (int)gid); 3624 3741 return 1; 3625 3742 } … … 3640 3757 char *targetsrc; 3641 3758 char *targetdest; 3759 NTSTATUS status; 3642 3760 3643 3761 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || … … 3663 3781 } 3664 3782 3665 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetsrc)) { 3666 d_printf("rename %s: %s\n", src, cli_errstr(cli)); 3667 return 1; 3668 } 3669 3670 if (!cli_resolve_path(ctx, "", auth_info, cli, dest, &targetcli, &targetdest)) { 3671 d_printf("rename %s: %s\n", dest, cli_errstr(cli)); 3672 return 1; 3673 } 3674 3675 if (!NT_STATUS_IS_OK(cli_rename(targetcli, targetsrc, targetdest))) { 3783 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3784 &targetsrc); 3785 if (!NT_STATUS_IS_OK(status)) { 3786 d_printf("rename %s: %s\n", src, nt_errstr(status)); 3787 return 1; 3788 } 3789 3790 status = cli_resolve_path(ctx, "", auth_info, cli, dest, &targetcli, 3791 &targetdest); 3792 if (!NT_STATUS_IS_OK(status)) { 3793 d_printf("rename %s: %s\n", dest, nt_errstr(status)); 3794 return 1; 3795 } 3796 3797 status = cli_rename(targetcli, targetsrc, targetdest); 3798 if (!NT_STATUS_IS_OK(status)) { 3676 3799 d_printf("%s renaming files %s -> %s \n", 3677 cli_errstr(targetcli),3800 nt_errstr(status), 3678 3801 targetsrc, 3679 3802 targetdest); … … 3684 3807 } 3685 3808 3686 /**************************************************************************** 3687 Print the volume name. 3688 ****************************************************************************/ 3689 3690 static int cmd_volume(void) 3691 { 3692 fstring volname; 3693 uint32 serial_num; 3694 time_t create_date; 3695 NTSTATUS status; 3696 3697 status = cli_get_fs_volume_info(cli, volname, &serial_num, 3698 &create_date); 3699 if (!NT_STATUS_IS_OK(status)) { 3700 d_printf("Error %s getting volume info\n", nt_errstr(status)); 3701 return 1; 3702 } 3703 3704 d_printf("Volume: |%s| serial number 0x%x\n", 3705 volname, (unsigned int)serial_num); 3706 return 0; 3707 } 3708 3709 /**************************************************************************** 3710 Hard link files using the NT call. 3711 ****************************************************************************/ 3712 3713 static int cmd_hardlink(void) 3809 struct scopy_timing { 3810 struct timespec tp_start; 3811 }; 3812 3813 static int scopy_status(off_t written, void *priv) 3814 { 3815 struct timespec tp_end; 3816 unsigned int scopy_total_time_ms; 3817 struct scopy_timing *st = priv; 3818 3819 clock_gettime_mono(&tp_end); 3820 scopy_total_time_ms = nsec_time_diff(&tp_end,&st->tp_start)/1000000; 3821 3822 DEBUG(5,("Copied %jd bytes at an average %3.1f kb/s\n", 3823 (intmax_t)written, written / (1.024*scopy_total_time_ms))); 3824 3825 return true; 3826 } 3827 3828 /**************************************************************************** 3829 Server-Side copy some file. 3830 ****************************************************************************/ 3831 3832 static int cmd_scopy(void) 3714 3833 { 3715 3834 TALLOC_CTX *ctx = talloc_tos(); … … 3717 3836 char *buf, *buf2; 3718 3837 struct cli_state *targetcli; 3719 char *targetname; 3838 char *targetsrc; 3839 char *targetdest; 3840 uint32_t DesiredAccess, ShareAccess, CreateDisposition, CreateOptions; 3841 struct smb_create_returns cr; 3842 uint16_t destfnum = (uint16_t)-1; 3843 uint16_t srcfnum = (uint16_t)-1; 3844 off_t written = 0; 3845 struct scopy_timing st; 3846 int rc = 0; 3847 NTSTATUS status; 3720 3848 3721 3849 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || 3722 3723 d_printf(" hardlink<src> <dest>\n");3850 !next_token_talloc(ctx, &cmd_ptr,&buf2,NULL)) { 3851 d_printf("scopy <src> <dest>\n"); 3724 3852 return 1; 3725 3853 } … … 3741 3869 } 3742 3870 3743 if (!cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, &targetname)) { 3744 d_printf("hardlink %s: %s\n", src, cli_errstr(cli)); 3745 return 1; 3746 } 3747 3748 if (!NT_STATUS_IS_OK(cli_nt_hardlink(targetcli, targetname, dest))) { 3749 d_printf("%s doing an NT hard link of files\n",cli_errstr(targetcli)); 3871 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 3872 &targetsrc); 3873 if (!NT_STATUS_IS_OK(status)) { 3874 d_printf("scopy %s: %s\n", src, nt_errstr(status)); 3875 return 1; 3876 } 3877 3878 status = cli_resolve_path(ctx, "", auth_info, cli, dest, &targetcli, 3879 &targetdest); 3880 if (!NT_STATUS_IS_OK(status)) { 3881 d_printf("scopy %s: %s\n", dest, nt_errstr(status)); 3882 return 1; 3883 } 3884 3885 3886 DesiredAccess = (FILE_READ_DATA|FILE_READ_EA|FILE_READ_ATTRIBUTES| 3887 READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS); 3888 ShareAccess = FILE_SHARE_READ|FILE_SHARE_DELETE; 3889 CreateDisposition = FILE_OPEN; 3890 CreateOptions = (FILE_SEQUENTIAL_ONLY|FILE_NON_DIRECTORY_FILE| 3891 FILE_OPEN_REPARSE_POINT); 3892 status = cli_ntcreate(targetcli, targetsrc, 0, DesiredAccess, 0, 3893 ShareAccess, CreateDisposition, CreateOptions, 0x0, 3894 &srcfnum, &cr); 3895 if (!NT_STATUS_IS_OK(status)) { 3896 d_printf("Failed to open file %s. %s\n", 3897 targetsrc, nt_errstr(status)); 3898 return 1; 3899 } 3900 3901 DesiredAccess = (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_READ_EA| 3902 FILE_WRITE_EA|FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES| 3903 DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|SYNCHRONIZE_ACCESS); 3904 ShareAccess = FILE_SHARE_NONE; 3905 CreateDisposition = FILE_CREATE; 3906 CreateOptions = FILE_SEQUENTIAL_ONLY|FILE_NON_DIRECTORY_FILE; 3907 status = cli_ntcreate(targetcli, targetdest, 0, DesiredAccess, 3908 FILE_ATTRIBUTE_ARCHIVE, ShareAccess, CreateDisposition, 3909 CreateOptions, 0x0, &destfnum, NULL); 3910 if (!NT_STATUS_IS_OK(status)) { 3911 d_printf("Failed to create file %s. %s\n", 3912 targetdest, nt_errstr(status)); 3913 cli_close(targetcli, srcfnum); 3914 return 1; 3915 } 3916 3917 clock_gettime_mono(&st.tp_start); 3918 status = cli_splice(targetcli, targetcli, srcfnum, destfnum, 3919 cr.end_of_file, 0, 0, &written, scopy_status, &st); 3920 if (!NT_STATUS_IS_OK(status)) { 3921 d_printf("%s copying file %s -> %s \n", 3922 nt_errstr(status), 3923 targetsrc, 3924 targetdest); 3925 rc = 1; 3926 } 3927 3928 status = cli_close(targetcli, srcfnum); 3929 if (!NT_STATUS_IS_OK(status)) { 3930 d_printf("Error %s closing remote source file\n", nt_errstr(status)); 3931 rc = 1; 3932 } 3933 status = cli_close(targetcli, destfnum); 3934 if (!NT_STATUS_IS_OK(status)) { 3935 d_printf("Error %s closing remote dest file\n", nt_errstr(status)); 3936 rc = 1; 3937 } 3938 3939 return rc; 3940 } 3941 3942 /**************************************************************************** 3943 Print the volume name. 3944 ****************************************************************************/ 3945 3946 static int cmd_volume(void) 3947 { 3948 char *volname; 3949 uint32_t serial_num; 3950 time_t create_date; 3951 NTSTATUS status; 3952 3953 status = cli_get_fs_volume_info(cli, talloc_tos(), 3954 &volname, &serial_num, 3955 &create_date); 3956 if (!NT_STATUS_IS_OK(status)) { 3957 d_printf("Error %s getting volume info\n", nt_errstr(status)); 3958 return 1; 3959 } 3960 3961 d_printf("Volume: |%s| serial number 0x%x\n", 3962 volname, (unsigned int)serial_num); 3963 return 0; 3964 } 3965 3966 /**************************************************************************** 3967 Hard link files using the NT call. 3968 ****************************************************************************/ 3969 3970 static int cmd_hardlink(void) 3971 { 3972 TALLOC_CTX *ctx = talloc_tos(); 3973 char *src, *dest; 3974 char *buf, *buf2; 3975 struct cli_state *targetcli; 3976 char *targetname; 3977 NTSTATUS status; 3978 3979 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || 3980 !next_token_talloc(ctx, &cmd_ptr,&buf2,NULL)) { 3981 d_printf("hardlink <src> <dest>\n"); 3982 return 1; 3983 } 3984 3985 src = talloc_asprintf(ctx, 3986 "%s%s", 3987 client_get_cur_dir(), 3988 buf); 3989 if (!src) { 3990 return 1; 3991 } 3992 3993 dest = talloc_asprintf(ctx, 3994 "%s%s", 3995 client_get_cur_dir(), 3996 buf2); 3997 if (!dest) { 3998 return 1; 3999 } 4000 4001 status = cli_resolve_path(ctx, "", auth_info, cli, src, &targetcli, 4002 &targetname); 4003 if (!NT_STATUS_IS_OK(status)) { 4004 d_printf("hardlink %s: %s\n", src, nt_errstr(status)); 4005 return 1; 4006 } 4007 4008 status = cli_nt_hardlink(targetcli, targetname, dest); 4009 if (!NT_STATUS_IS_OK(status)) { 4010 d_printf("%s doing an NT hard link of files\n", 4011 nt_errstr(status)); 3750 4012 return 1; 3751 4013 } … … 3794 4056 3795 4057 /**************************************************************************** 4058 Watch directory changes 4059 ****************************************************************************/ 4060 4061 static int cmd_notify(void) 4062 { 4063 TALLOC_CTX *frame = talloc_stackframe(); 4064 char *name, *buf; 4065 NTSTATUS status; 4066 uint16_t fnum; 4067 4068 name = talloc_strdup(talloc_tos(), client_get_cur_dir()); 4069 if (name == NULL) { 4070 goto fail; 4071 } 4072 if (!next_token_talloc(talloc_tos(), &cmd_ptr, &buf, NULL)) { 4073 goto usage; 4074 } 4075 name = talloc_asprintf_append(name, "%s", buf); 4076 if (name == NULL) { 4077 goto fail; 4078 } 4079 status = cli_ntcreate( 4080 cli, name, 0, FILE_READ_DATA, 0, 4081 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 4082 FILE_OPEN, 0, 0, &fnum, NULL); 4083 if (!NT_STATUS_IS_OK(status)) { 4084 d_printf("Could not open file: %s\n", nt_errstr(status)); 4085 goto fail; 4086 } 4087 4088 while (1) { 4089 uint32_t i, num_changes; 4090 struct notify_change *changes; 4091 4092 status = cli_notify(cli, fnum, 1000, FILE_NOTIFY_CHANGE_ALL, 4093 true, 4094 talloc_tos(), &num_changes, &changes); 4095 if (!NT_STATUS_IS_OK(status)) { 4096 d_printf("notify returned %s\n", 4097 nt_errstr(status)); 4098 goto fail; 4099 } 4100 for (i=0; i<num_changes; i++) { 4101 printf("%4.4x %s\n", changes[i].action, 4102 changes[i].name); 4103 } 4104 TALLOC_FREE(changes); 4105 } 4106 usage: 4107 d_printf("notify <file>\n"); 4108 fail: 4109 TALLOC_FREE(frame); 4110 return 1; 4111 } 4112 4113 /**************************************************************************** 3796 4114 Set the archive level. 3797 4115 ****************************************************************************/ … … 3812 4130 3813 4131 /**************************************************************************** 4132 Toggle the backup_intent state. 4133 ****************************************************************************/ 4134 4135 static int cmd_backup(void) 4136 { 4137 backup_intent = !backup_intent; 4138 cli_set_backup_intent(cli, backup_intent); 4139 DEBUG(2,("backup intent is now %s\n",backup_intent?"on":"off")); 4140 return 1; 4141 } 4142 4143 /**************************************************************************** 3814 4144 Toggle the lowercaseflag. 3815 4145 ****************************************************************************/ … … 3887 4217 } 3888 4218 } 3889 d = TALLOC_ARRAY(ctx, char, PATH_MAX+1);4219 d = sys_getwd(); 3890 4220 if (!d) { 3891 4221 return 1; 3892 4222 } 3893 DEBUG(2,("the local directory is now %s\n",sys_getwd(d))); 4223 DEBUG(2,("the local directory is now %s\n",d)); 4224 SAFE_FREE(d); 3894 4225 return 0; 3895 4226 } … … 3984 4315 ****************************************************************************/ 3985 4316 3986 static void browse_fn(const char *name, uint32 m,4317 static void browse_fn(const char *name, uint32_t m, 3987 4318 const char *comment, void *state) 3988 4319 { … … 4027 4358 struct dcerpc_binding_handle *b; 4028 4359 4029 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc .syntax_id,4360 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc, 4030 4361 &pipe_hnd); 4031 4362 … … 4085 4416 } 4086 4417 4087 if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1) 4088 d_printf("Error returning browse list: %s\n", cli_errstr(cli)); 4418 if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1) { 4419 NTSTATUS status = cli_nt_error(cli); 4420 d_printf("Error returning browse list: %s\n", 4421 nt_errstr(status)); 4422 } 4089 4423 4090 4424 return (ret != -1); … … 4095 4429 ****************************************************************************/ 4096 4430 4097 static void server_fn(const char *name, uint32 m,4431 static void server_fn(const char *name, uint32_t m, 4098 4432 const char *comment, void *state) 4099 4433 { … … 4146 4480 4147 4481 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 4148 d_printf("Current VUID is %d\n", cli->vuid); 4482 d_printf("Current VUID is %d\n", 4483 cli_state_get_uid(cli)); 4149 4484 return 0; 4150 4485 } 4151 4486 4152 cli ->vuid = atoi(buf);4487 cli_state_set_uid(cli, atoi(buf)); 4153 4488 return 0; 4154 4489 } … … 4170 4505 4171 4506 if (!next_token_talloc(ctx, &cmd_ptr,&l_password,NULL)) { 4172 char *pass = getpass("Password: "); 4173 if (pass) { 4174 l_password = talloc_strdup(ctx,pass); 4507 char pwd[256] = {0}; 4508 int rc; 4509 4510 rc = samba_getpass("Password: ", pwd, sizeof(pwd), false, false); 4511 if (rc == 0) { 4512 l_password = talloc_strdup(ctx, pwd); 4175 4513 } 4176 4514 } … … 4188 4526 } 4189 4527 4190 d_printf("Current VUID is %d\n", cli->vuid); 4528 d_printf("Current VUID is %d\n", cli_state_get_uid(cli)); 4529 return 0; 4530 } 4531 4532 /** 4533 * close the session 4534 */ 4535 4536 static int cmd_logoff(void) 4537 { 4538 NTSTATUS status; 4539 4540 status = cli_ulogoff(cli); 4541 if (!NT_STATUS_IS_OK(status)) { 4542 d_printf("logoff failed: %s\n", nt_errstr(status)); 4543 return -1; 4544 } 4545 4546 d_printf("logoff successful\n"); 4547 return 0; 4548 } 4549 4550 4551 /** 4552 * tree connect (connect to a share) 4553 */ 4554 4555 static int cmd_tcon(void) 4556 { 4557 TALLOC_CTX *ctx = talloc_tos(); 4558 char *sharename; 4559 NTSTATUS status; 4560 4561 if (!next_token_talloc(ctx, &cmd_ptr, &sharename, NULL)) { 4562 d_printf("tcon <sharename>\n"); 4563 return 0; 4564 } 4565 4566 if (!sharename) { 4567 return 1; 4568 } 4569 4570 status = cli_tree_connect(cli, sharename, "?????", "", 0); 4571 if (!NT_STATUS_IS_OK(status)) { 4572 d_printf("tcon failed: %s\n", nt_errstr(status)); 4573 return -1; 4574 } 4575 4576 talloc_free(sharename); 4577 4578 d_printf("tcon to %s successful, tid: %u\n", sharename, 4579 cli_state_get_tid(cli)); 4580 return 0; 4581 } 4582 4583 /** 4584 * tree disconnect (disconnect from a share) 4585 */ 4586 4587 static int cmd_tdis(void) 4588 { 4589 NTSTATUS status; 4590 4591 status = cli_tdis(cli); 4592 if (!NT_STATUS_IS_OK(status)) { 4593 d_printf("tdis failed: %s\n", nt_errstr(status)); 4594 return -1; 4595 } 4596 4597 d_printf("tdis successful\n"); 4598 return 0; 4599 } 4600 4601 4602 /** 4603 * get or set tid 4604 */ 4605 4606 static int cmd_tid(void) 4607 { 4608 TALLOC_CTX *ctx = talloc_tos(); 4609 char *tid_str; 4610 4611 if (!next_token_talloc(ctx, &cmd_ptr, &tid_str, NULL)) { 4612 if (cli_state_has_tcon(cli)) { 4613 d_printf("current tid is %d\n", cli_state_get_tid(cli)); 4614 } else { 4615 d_printf("no tcon currently\n"); 4616 } 4617 } else { 4618 uint16_t tid = atoi(tid_str); 4619 cli_state_set_tid(cli, tid); 4620 } 4621 4191 4622 return 0; 4192 4623 } … … 4212 4643 struct cli_state *targetcli; 4213 4644 char *targetpath; 4214 4215 if (!cli_resolve_path(ctx, "", auth_info, cli, client_get_cur_dir(), 4216 &targetcli, &targetpath ) ) { 4217 d_printf("showconnect %s: %s\n", cur_dir, cli_errstr(cli)); 4218 return 1; 4219 } 4220 4221 d_printf("//%s/%s\n", targetcli->desthost, targetcli->share); 4222 return 0; 4645 NTSTATUS status; 4646 4647 status = cli_resolve_path(ctx, "", auth_info, cli, 4648 client_get_cur_dir(), &targetcli, 4649 &targetpath); 4650 if (!NT_STATUS_IS_OK(status)) { 4651 d_printf("showconnect %s: %s\n", cur_dir, nt_errstr(status)); 4652 return 1; 4653 } 4654 4655 d_printf("//%s/%s\n", smbXcli_conn_remote_name(targetcli->conn), targetcli->share); 4656 return 0; 4657 } 4658 4659 /** 4660 * set_remote_attr - set DOS attributes of a remote file 4661 * @filename: path to the file name 4662 * @new_attr: attribute bit mask to use 4663 * @mode: one of ATTR_SET or ATTR_UNSET 4664 * 4665 * Update the file attributes with the one provided. 4666 */ 4667 int set_remote_attr(const char *filename, uint16_t new_attr, int mode) 4668 { 4669 extern struct cli_state *cli; 4670 uint16_t old_attr; 4671 NTSTATUS status; 4672 4673 status = cli_getatr(cli, filename, &old_attr, NULL, NULL); 4674 if (!NT_STATUS_IS_OK(status)) { 4675 d_printf("cli_getatr failed: %s\n", nt_errstr(status)); 4676 return 1; 4677 } 4678 4679 if (mode == ATTR_SET) { 4680 new_attr |= old_attr; 4681 } else { 4682 new_attr = old_attr & ~new_attr; 4683 } 4684 4685 status = cli_setatr(cli, filename, new_attr, 0); 4686 if (!NT_STATUS_IS_OK(status)) { 4687 d_printf("cli_setatr failed: %s\n", nt_errstr(status)); 4688 return 1; 4689 } 4690 4691 return 0; 4692 } 4693 4694 /** 4695 * cmd_setmode - interactive command to set DOS attributes 4696 * 4697 * Read a filename and mode from the client command line and update 4698 * the file DOS attributes. 4699 */ 4700 int cmd_setmode(void) 4701 { 4702 const extern char *cmd_ptr; 4703 char *buf; 4704 char *fname = NULL; 4705 uint16_t attr[2] = {0}; 4706 int mode = ATTR_SET; 4707 int err = 0; 4708 bool ok; 4709 TALLOC_CTX *ctx = talloc_new(NULL); 4710 if (ctx == NULL) { 4711 return 1; 4712 } 4713 4714 ok = next_token_talloc(ctx, &cmd_ptr, &buf, NULL); 4715 if (!ok) { 4716 d_printf("setmode <filename> <[+|-]rsha>\n"); 4717 err = 1; 4718 goto out; 4719 } 4720 4721 fname = talloc_asprintf(ctx, 4722 "%s%s", 4723 client_get_cur_dir(), 4724 buf); 4725 if (fname == NULL) { 4726 err = 1; 4727 goto out; 4728 } 4729 4730 while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL)) { 4731 const char *s = buf; 4732 4733 while (*s) { 4734 switch (*s++) { 4735 case '+': 4736 mode = ATTR_SET; 4737 break; 4738 case '-': 4739 mode = ATTR_UNSET; 4740 break; 4741 case 'r': 4742 attr[mode] |= FILE_ATTRIBUTE_READONLY; 4743 break; 4744 case 'h': 4745 attr[mode] |= FILE_ATTRIBUTE_HIDDEN; 4746 break; 4747 case 's': 4748 attr[mode] |= FILE_ATTRIBUTE_SYSTEM; 4749 break; 4750 case 'a': 4751 attr[mode] |= FILE_ATTRIBUTE_ARCHIVE; 4752 break; 4753 default: 4754 d_printf("setmode <filename> <perm=[+|-]rsha>\n"); 4755 err = 1; 4756 goto out; 4757 } 4758 } 4759 } 4760 4761 if (attr[ATTR_SET] == 0 && attr[ATTR_UNSET] == 0) { 4762 d_printf("setmode <filename> <[+|-]rsha>\n"); 4763 err = 1; 4764 goto out; 4765 } 4766 4767 DEBUG(2, ("perm set %d %d\n", attr[ATTR_SET], attr[ATTR_UNSET])); 4768 4769 /* ignore return value: server might not store DOS attributes */ 4770 set_remote_attr(fname, attr[ATTR_SET], ATTR_SET); 4771 set_remote_attr(fname, attr[ATTR_UNSET], ATTR_UNSET); 4772 out: 4773 talloc_free(ctx); 4774 return err; 4223 4775 } 4224 4776 … … 4234 4786 4235 4787 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 4236 if (!smb_encrypt) { 4237 d_printf("iosize <n> or iosize 0x<n>. " 4238 "Minimum is 16384 (0x4000), " 4239 "max is 16776960 (0xFFFF00)\n"); 4788 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { 4789 if (!smb_encrypt) { 4790 d_printf("iosize <n> or iosize 0x<n>. " 4791 "Minimum is 0 (default), " 4792 "max is 16776960 (0xFFFF00)\n"); 4793 } else { 4794 d_printf("iosize <n> or iosize 0x<n>. " 4795 "(Encrypted connection) ," 4796 "Minimum is 0 (default), " 4797 "max is 130048 (0x1FC00)\n"); 4798 } 4240 4799 } else { 4241 d_printf("iosize <n> or iosize 0x<n>. " 4242 "(Encrypted connection) ," 4243 "Minimum is 16384 (0x4000), " 4244 "max is 130048 (0x1FC00)\n"); 4800 d_printf("iosize <n> or iosize 0x<n>.\n"); 4245 4801 } 4246 4802 return 1; … … 4248 4804 4249 4805 iosize = strtol(buf,NULL,0); 4250 if (smb_encrypt && (iosize < 0x4000 || iosize > 0xFC00)) { 4251 d_printf("iosize out of range for encrypted " 4252 "connection (min = 16384 (0x4000), " 4253 "max = 130048 (0x1FC00)"); 4254 return 1; 4255 } else if (!smb_encrypt && (iosize < 0x4000 || iosize > 0xFFFF00)) { 4256 d_printf("iosize out of range (min = 16384 (0x4000), " 4257 "max = 16776960 (0xFFFF00)"); 4258 return 1; 4806 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { 4807 if (smb_encrypt && (iosize < 0 || iosize > 0xFC00)) { 4808 d_printf("iosize out of range for encrypted " 4809 "connection (min = 0 (default), " 4810 "max = 130048 (0x1FC00)\n"); 4811 return 1; 4812 } else if (!smb_encrypt && (iosize < 0 || iosize > 0xFFFF00)) { 4813 d_printf("iosize out of range (min = 0 (default), " 4814 "max = 16776960 (0xFFFF00)\n"); 4815 return 1; 4816 } 4259 4817 } 4260 4818 … … 4263 4821 return 0; 4264 4822 } 4823 4824 /**************************************************************************** 4825 timeout command 4826 ***************************************************************************/ 4827 4828 static int cmd_timeout(void) 4829 { 4830 TALLOC_CTX *ctx = talloc_tos(); 4831 char *buf; 4832 4833 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 4834 unsigned int old_timeout = cli_set_timeout(cli, 0); 4835 cli_set_timeout(cli, old_timeout); 4836 d_printf("timeout <n> (per-operation timeout " 4837 "in seconds - currently %u).\n", 4838 old_timeout/1000); 4839 return 1; 4840 } 4841 4842 io_timeout = strtol(buf,NULL,0); 4843 cli_set_timeout(cli, io_timeout*1000); 4844 d_printf("io_timeout per operation is now %d\n", io_timeout); 4845 return 0; 4846 } 4847 4265 4848 4266 4849 /**************************************************************************** … … 4307 4890 {"altname",cmd_altname,"<file> show alt name",{COMPL_NONE,COMPL_NONE}}, 4308 4891 {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}}, 4892 {"backup",cmd_backup,"toggle backup intent state",{COMPL_NONE,COMPL_NONE}}, 4309 4893 {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}}, 4310 4894 {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}}, 4311 4895 {"case_sensitive",cmd_setcase,"toggle the case sensitive flag to server",{COMPL_NONE,COMPL_NONE}}, 4312 4896 {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}}, 4313 {"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_ REMOTE}},4314 {"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_ REMOTE}},4315 {"close",cmd_close,"<fid> close a file given a fid",{COMPL_REMOTE,COMPL_ REMOTE}},4897 {"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_NONE}}, 4898 {"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_NONE}}, 4899 {"close",cmd_close,"<fid> close a file given a fid",{COMPL_REMOTE,COMPL_NONE}}, 4316 4900 {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}}, 4317 4901 {"dir",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}}, … … 4320 4904 {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}}, 4321 4905 {"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}}, 4322 {"getfacl",cmd_getfacl,"<file name> get the POSIX ACL on a file (UNIX extensions only)",{COMPL_REMOTE,COMPL_ LOCAL}},4906 {"getfacl",cmd_getfacl,"<file name> get the POSIX ACL on a file (UNIX extensions only)",{COMPL_REMOTE,COMPL_NONE}}, 4323 4907 {"geteas", cmd_geteas, "<file name> get the EA list of a file", 4324 {COMPL_REMOTE, COMPL_ LOCAL}},4908 {COMPL_REMOTE, COMPL_NONE}}, 4325 4909 {"hardlink",cmd_hardlink,"<src> <dest> create a Windows hard link",{COMPL_REMOTE,COMPL_REMOTE}}, 4326 4910 {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}}, … … 4330 4914 {"link",cmd_link,"<oldname> <newname> create a UNIX hard link",{COMPL_REMOTE,COMPL_REMOTE}}, 4331 4915 {"lock",cmd_lock,"lock <fnum> [r|w] <hex-start> <hex-len> : set a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}}, 4332 {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}}, 4916 {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}}, 4333 4917 {"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}}, 4334 4918 {"l",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}}, … … 4337 4921 {"mget",cmd_mget,"<mask> get all the matching files",{COMPL_REMOTE,COMPL_NONE}}, 4338 4922 {"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}}, 4339 {"more",cmd_more,"<remote name> view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}}, 4923 {"more",cmd_more,"<remote name> view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}}, 4340 4924 {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}}, 4341 4925 {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}}, 4926 {"notify",cmd_notify,"<file>Get notified of dir changes",{COMPL_REMOTE,COMPL_NONE}}, 4342 4927 {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}}, 4343 4928 {"posix", cmd_posix, "turn on all POSIX capabilities", {COMPL_REMOTE,COMPL_NONE}}, … … 4348 4933 {"posix_unlink",cmd_posix_unlink,"<name> removes a file using POSIX interface",{COMPL_REMOTE,COMPL_NONE}}, 4349 4934 {"print",cmd_print,"<file name> print a file",{COMPL_NONE,COMPL_NONE}}, 4350 {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}}, 4935 {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}}, 4351 4936 {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}}, 4352 4937 {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}}, … … 4356 4941 {"readlink",cmd_readlink,"filename Do a UNIX extensions readlink call on a symlink",{COMPL_REMOTE,COMPL_REMOTE}}, 4357 4942 {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}}, 4358 {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}}, 4943 {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}}, 4359 4944 {"reget",cmd_reget,"<remote name> [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}}, 4360 4945 {"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}}, 4361 4946 {"reput",cmd_reput,"<local name> [remote name] put a file restarting at end of remote file",{COMPL_LOCAL,COMPL_REMOTE}}, 4362 4947 {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}}, 4363 {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_ NONE,COMPL_NONE}},4364 {"showacls",cmd_showacls,"toggle if ACLs are shown or not",{COMPL_NONE,COMPL_NONE}}, 4948 {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_REMOTE,COMPL_NONE}}, 4949 {"showacls",cmd_showacls,"toggle if ACLs are shown or not",{COMPL_NONE,COMPL_NONE}}, 4365 4950 {"setea", cmd_setea, "<file name> <eaname> <eaval> Set an EA of a file", 4366 4951 {COMPL_REMOTE, COMPL_LOCAL}}, 4367 {"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}}, 4368 {"stat",cmd_stat,"filename Do a UNIX extensions stat call on a file",{COMPL_REMOTE,COMPL_REMOTE}}, 4952 {"setmode",cmd_setmode,"<file name> <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}}, 4953 {"scopy",cmd_scopy,"<src> <dest> server-side copy file",{COMPL_REMOTE,COMPL_REMOTE}}, 4954 {"stat",cmd_stat,"<file name> Do a UNIX extensions stat call on a file",{COMPL_REMOTE,COMPL_NONE}}, 4369 4955 {"symlink",cmd_symlink,"<oldname> <newname> create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}}, 4370 4956 {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}}, 4371 4957 {"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}}, 4958 {"timeout",cmd_timeout,"timeout <number> - set the per-operation timeout in seconds (default 20)",{COMPL_NONE,COMPL_NONE}}, 4372 4959 {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}}, 4373 4960 {"unlock",cmd_unlock,"unlock <fnum> <hex-start> <hex-len> : remove a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}}, … … 4378 4965 {"listconnect",cmd_list_connect,"list open connections",{COMPL_NONE,COMPL_NONE}}, 4379 4966 {"showconnect",cmd_show_connect,"display the current active connection",{COMPL_NONE,COMPL_NONE}}, 4967 {"tcon",cmd_tcon,"connect to a share" ,{COMPL_NONE,COMPL_NONE}}, 4968 {"tdis",cmd_tdis,"disconnect from a share",{COMPL_NONE,COMPL_NONE}}, 4969 {"tid",cmd_tid,"show or set the current tid (tree-id)",{COMPL_NONE,COMPL_NONE}}, 4970 {"logoff",cmd_logoff,"log off (close the session)",{COMPL_NONE,COMPL_NONE}}, 4380 4971 {"..",cmd_cd_oneup,"change the remote directory (up one level)",{COMPL_REMOTE,COMPL_NONE}}, 4381 4972 … … 4458 5049 4459 5050 if (!cli) { 4460 cli = cli_cm_open(talloc_tos(), NULL, 4461 have_ip ? dest_ss_str : desthost, 4462 service, auth_info, 4463 true, smb_encrypt, 4464 max_protocol, port, name_type); 4465 if (!cli) { 5051 NTSTATUS status; 5052 5053 status = cli_cm_open(talloc_tos(), NULL, 5054 have_ip ? dest_ss_str : desthost, 5055 service, auth_info, 5056 true, smb_encrypt, 5057 max_protocol, port, name_type, 5058 &cli); 5059 if (!NT_STATUS_IS_OK(status)) { 4466 5060 return 1; 4467 5061 } 5062 cli_set_timeout(cli, io_timeout*1000); 4468 5063 } 4469 5064 … … 4638 5233 } 4639 5234 4640 if (!cli_resolve_path(ctx, "", auth_info, cli, dirmask, &targetcli, &targetpath)) { 5235 status = cli_resolve_path(ctx, "", auth_info, cli, dirmask, &targetcli, 5236 &targetpath); 5237 if (!NT_STATUS_IS_OK(status)) { 4641 5238 goto cleanup; 4642 5239 } … … 4676 5273 info.matches[0] = SMB_STRNDUP(info.matches[1], info.samelen); 4677 5274 info.matches[info.count] = NULL; 5275 TALLOC_FREE(ctx); 4678 5276 return info.matches; 4679 5277 … … 4788 5386 struct timespec now; 4789 5387 time_t t; 4790 int ret, revents; 5388 NTSTATUS status; 5389 unsigned char garbage[16]; 4791 5390 4792 5391 clock_gettime_mono(&now); … … 4798 5397 last_t = t; 4799 5398 4800 again: 4801 4802 if (cli->fd == -1) 5399 /* Ping the server to keep the connection alive using SMBecho. */ 5400 memset(garbage, 0xf0, sizeof(garbage)); 5401 status = cli_echo(cli, 1, data_blob_const(garbage, sizeof(garbage))); 5402 if (NT_STATUS_IS_OK(status)) { 4803 5403 return; 4804 4805 /* We deliberately use receive_smb_raw instead of 4806 client_receive_smb as we want to receive 4807 session keepalives and then drop them here. 4808 */ 4809 4810 ret = poll_intr_one_fd(cli->fd, POLLIN|POLLHUP, 0, &revents); 4811 4812 if ((ret > 0) && (revents & (POLLIN|POLLHUP|POLLERR))) { 4813 NTSTATUS status; 4814 size_t len; 4815 4816 set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); 4817 4818 status = receive_smb_raw(cli->fd, cli->inbuf, cli->bufsize, 0, 0, &len); 4819 4820 if (!NT_STATUS_IS_OK(status)) { 4821 DEBUG(0, ("Read from server failed, maybe it closed " 4822 "the connection\n")); 4823 4824 finished = true; 4825 smb_readline_done(); 4826 if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { 4827 set_smb_read_error(&cli->smb_rw_error, 4828 SMB_READ_EOF); 4829 return; 4830 } 4831 4832 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 4833 set_smb_read_error(&cli->smb_rw_error, 4834 SMB_READ_TIMEOUT); 4835 return; 4836 } 4837 4838 set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); 4839 return; 4840 } 4841 if(CVAL(cli->inbuf,0) != SMBkeepalive) { 4842 DEBUG(0, ("Read from server " 4843 "returned unexpected packet!\n")); 4844 return; 4845 } 4846 4847 goto again; 4848 } 4849 4850 /* Ping the server to keep the connection alive using SMBecho. */ 4851 { 4852 NTSTATUS status; 4853 unsigned char garbage[16]; 4854 memset(garbage, 0xf0, sizeof(garbage)); 4855 status = cli_echo(cli, 1, data_blob_const(garbage, sizeof(garbage))); 4856 4857 if (NT_STATUS_IS_OK(status)) { 4858 return; 4859 } 4860 4861 if (!cli_state_is_connected(cli)) { 4862 DEBUG(0, ("SMBecho failed (%s). The connection is " 4863 "disconnected now\n", nt_errstr(status))); 4864 finished = true; 4865 smb_readline_done(); 4866 } 5404 } 5405 5406 if (!cli_state_is_connected(cli)) { 5407 DEBUG(0,("SMBecho failed (%s). The connection is " 5408 "disconnected now\n", nt_errstr(status))); 5409 finished = true; 5410 smb_readline_done(); 4867 5411 } 4868 5412 } … … 4934 5478 { 4935 5479 int rc = 0; 4936 4937 cli = cli_cm_open(talloc_tos(), NULL, 4938 have_ip ? dest_ss_str : desthost, 4939 service, auth_info, true, smb_encrypt, 4940 max_protocol, port, name_type); 4941 if (!cli) { 4942 return 1; 4943 } 5480 NTSTATUS status; 5481 5482 status = cli_cm_open(talloc_tos(), NULL, 5483 have_ip ? dest_ss_str : desthost, 5484 service, auth_info, true, smb_encrypt, 5485 max_protocol, port, name_type, &cli); 5486 if (!NT_STATUS_IS_OK(status)) { 5487 return 1; 5488 } 5489 5490 cli_set_timeout(cli, io_timeout*1000); 4944 5491 4945 5492 if (base_directory && *base_directory) { … … 4967 5514 static int do_host_query(const char *query_host) 4968 5515 { 4969 cli = cli_cm_open(talloc_tos(), NULL, 4970 have_ip ? dest_ss_str : query_host, "IPC$", auth_info, true, smb_encrypt, 4971 max_protocol, port, name_type); 4972 if (!cli) 4973 return 1; 4974 5516 NTSTATUS status; 5517 5518 status = cli_cm_open(talloc_tos(), NULL, 5519 have_ip ? dest_ss_str : query_host, 5520 "IPC$", auth_info, true, smb_encrypt, 5521 max_protocol, port, name_type, &cli); 5522 if (!NT_STATUS_IS_OK(status)) { 5523 return 1; 5524 } 5525 5526 cli_set_timeout(cli, io_timeout*1000); 4975 5527 browse_host(true); 4976 5528 … … 4987 5539 } 4988 5540 4989 if (port != 139) {5541 if (port != NBT_SMB_PORT) { 4990 5542 4991 5543 /* Workgroups simply don't make sense over anything … … 4993 5545 4994 5546 cli_shutdown(cli); 4995 cli = cli_cm_open(talloc_tos(), NULL, 4996 have_ip ? dest_ss_str : query_host, "IPC$", 4997 auth_info, true, smb_encrypt, 4998 max_protocol, 139, name_type); 5547 status = cli_cm_open(talloc_tos(), NULL, 5548 have_ip ? dest_ss_str : query_host, 5549 "IPC$", auth_info, true, smb_encrypt, 5550 max_protocol, NBT_SMB_PORT, name_type, 5551 &cli); 5552 if (!NT_STATUS_IS_OK(status)) { 5553 cli = NULL; 5554 } 4999 5555 } 5000 5556 5001 5557 if (cli == NULL) { 5002 5558 d_printf("NetBIOS over TCP disabled -- no workgroup available\n"); 5003 return 1; 5004 } 5005 5559 return 0; 5560 } 5561 5562 cli_set_timeout(cli, io_timeout*1000); 5006 5563 list_servers(lp_workgroup()); 5007 5564 … … 5017 5574 static int do_tar_op(const char *base_directory) 5018 5575 { 5019 int ret; 5576 struct tar *tar_ctx = tar_get_ctx(); 5577 int ret = 0; 5020 5578 5021 5579 /* do we already have a connection? */ 5022 5580 if (!cli) { 5023 cli = cli_cm_open(talloc_tos(), NULL, 5024 have_ip ? dest_ss_str : desthost, 5025 service, auth_info, true, smb_encrypt, 5026 max_protocol, port, name_type); 5027 if (!cli) 5028 return 1; 5029 } 5030 5031 recurse=true; 5581 NTSTATUS status; 5582 5583 status = cli_cm_open(talloc_tos(), NULL, 5584 have_ip ? dest_ss_str : desthost, 5585 service, auth_info, true, smb_encrypt, 5586 max_protocol, port, name_type, &cli); 5587 if (!NT_STATUS_IS_OK(status)) { 5588 ret = 1; 5589 goto out; 5590 } 5591 cli_set_timeout(cli, io_timeout*1000); 5592 } 5593 5594 recurse = true; 5032 5595 5033 5596 if (base_directory && *base_directory) { 5034 5597 ret = do_cd(base_directory); 5035 5598 if (ret) { 5036 cli_shutdown(cli);5037 return ret;5038 5039 } 5040 5041 ret=process_tar(); 5042 5599 goto out_cli; 5600 } 5601 } 5602 5603 ret = tar_process(tar_ctx); 5604 5605 out_cli: 5043 5606 cli_shutdown(cli); 5044 5045 return (ret);5607 out: 5608 return ret; 5046 5609 } 5047 5610 … … 5052 5615 static int do_message_op(struct user_auth_info *a_info) 5053 5616 { 5054 struct sockaddr_storage ss;5055 struct nmb_name called, calling;5056 fstring server_name;5057 char name_type_hex[10];5058 int msg_port;5059 5617 NTSTATUS status; 5060 5618 5061 make_nmb_name(&calling, calling_name, 0x0); 5062 make_nmb_name(&called , desthost, name_type); 5063 5064 fstrcpy(server_name, desthost); 5065 snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type); 5066 fstrcat(server_name, name_type_hex); 5067 5068 zero_sockaddr(&ss); 5069 if (have_ip) 5070 ss = dest_ss; 5071 5072 /* we can only do messages over port 139 (to windows clients at least) */ 5073 5074 msg_port = port ? port : 139; 5075 5076 if (!(cli=cli_initialise())) { 5077 d_printf("Connection to %s failed\n", desthost); 5078 return 1; 5079 } 5080 cli_set_port(cli, msg_port); 5081 5082 status = cli_connect(cli, server_name, &ss); 5619 status = cli_connect_nb(desthost, have_ip ? &dest_ss : NULL, 5620 port ? port : NBT_SMB_PORT, name_type, 5621 lp_netbios_name(), SMB_SIGNING_DEFAULT, 0, &cli); 5083 5622 if (!NT_STATUS_IS_OK(status)) { 5084 5623 d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status)); … … 5086 5625 } 5087 5626 5088 if (!cli_session_request(cli, &calling, &called)) { 5089 d_printf("session request failed\n"); 5090 cli_shutdown(cli); 5091 return 1; 5092 } 5093 5627 cli_set_timeout(cli, io_timeout*1000); 5094 5628 send_message(get_cmdline_auth_info_username(a_info)); 5095 5629 cli_shutdown(cli); … … 5102 5636 ****************************************************************************/ 5103 5637 5104 int main(int argc,char *argv[]) 5105 { 5638 int main(int argc,char *argv[]) 5639 { 5640 const char **const_argv = discard_const_p(const char *, argv); 5106 5641 char *base_directory = NULL; 5107 5642 int opt; … … 5112 5647 char *p; 5113 5648 int rc = 0; 5114 fstring new_workgroup;5115 5649 bool tar_opt = false; 5116 5650 bool service_opt = false; 5651 struct tar *tar_ctx = tar_get_ctx(); 5652 5117 5653 struct poptOption long_options[] = { 5118 5654 POPT_AUTOHELP … … 5126 5662 { "tar", 'T', POPT_ARG_STRING, NULL, 'T', "Command line tar", "<c|x>IXFqgbNan" }, 5127 5663 { "directory", 'D', POPT_ARG_STRING, NULL, 'D', "Start from directory", "DIR" }, 5128 { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" }, 5664 { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" }, 5129 5665 { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" }, 5666 { "timeout", 't', POPT_ARG_INT, &io_timeout, 'b', "Changes the per-operation timeout", "SECONDS" }, 5130 5667 { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" }, 5131 5668 { "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" }, … … 5142 5679 } 5143 5680 5144 /* initialize the workgroup name so we can determine whether or5145 not it was set by a command line option */5146 5147 set_global_myworkgroup( "" );5148 set_global_myname( "" );5149 5150 5681 /* set default debug level to 1 regardless of what smb.conf sets */ 5151 5682 setup_logging( "smbclient", DEBUG_DEFAULT_STDERR ); 5152 load_case_tables();5683 smb_init_locale(); 5153 5684 5154 5685 lp_set_cmdline("log level", "1"); … … 5161 5692 5162 5693 /* skip argv(0) */ 5163 pc = poptGetContext("smbclient", argc, (const char **)argv, long_options, 0);5694 pc = poptGetContext("smbclient", argc, const_argv, long_options, 0); 5164 5695 poptSetOtherOptionHelp(pc, "service <password>"); 5165 5166 lp_set_in_client(true); /* Make sure that we tell lp_load we are */5167 5696 5168 5697 while ((opt = poptGetNextOpt(pc)) != -1) { … … 5193 5722 poptGetArg(pc)); 5194 5723 } 5724 5195 5725 5196 5726 switch (opt) { … … 5206 5736 } 5207 5737 if( !port ) 5208 port = 139;5738 port = NBT_SMB_PORT; 5209 5739 message = true; 5210 5740 break; … … 5230 5760 break; 5231 5761 case 'm': 5232 max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol);5762 lp_set_cmdline("client max protocol", poptGetOptArg(pc)); 5233 5763 break; 5234 5764 case 'T': … … 5237 5767 { 5238 5768 int i; 5769 5239 5770 for (i = 1; i < argc; i++) { 5240 5771 if (strncmp("-T", argv[i],2)==0) … … 5242 5773 } 5243 5774 i++; 5244 if (!tar_parseargs(argc, argv, poptGetOptArg(pc), i)) { 5775 if (tar_parse_args(tar_ctx, poptGetOptArg(pc), 5776 const_argv + i, argc - i)) { 5245 5777 poptPrintUsage(pc, stderr, 0); 5246 5778 exit(1); … … 5293 5825 } 5294 5826 5295 /* save the workgroup...5296 5297 FIXME!! do we need to do this for other options as well5298 (or maybe a generic way to keep lp_load() from overwriting5299 everything)? */5300 5301 fstrcpy( new_workgroup, lp_workgroup() );5302 calling_name = talloc_strdup(frame, global_myname() );5303 if (!calling_name) {5304 exit(ENOMEM);5305 }5306 5307 5827 if ( override_logfile ) 5308 setup_logging( lp_logfile( ), DEBUG_FILE );5309 5310 if (!lp_load (get_dyn_CONFIGFILE(),true,false,false,true)) {5828 setup_logging( lp_logfile(talloc_tos()), DEBUG_FILE ); 5829 5830 if (!lp_load_client(get_dyn_CONFIGFILE())) { 5311 5831 fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", 5312 5832 argv[0], get_dyn_CONFIGFILE()); … … 5338 5858 } 5339 5859 5340 if ( strlen(new_workgroup) != 0 ) {5341 set_global_myworkgroup( new_workgroup );5342 }5343 5344 if ( strlen(calling_name) != 0 ) {5345 set_global_myname( calling_name );5346 } else {5347 TALLOC_FREE(calling_name);5348 calling_name = talloc_strdup(frame, global_myname() );5349 }5350 5351 5860 smb_encrypt = get_cmdline_auth_info_smb_encrypt(auth_info); 5352 5861 if (!init_names()) { … … 5356 5865 5357 5866 if(new_name_resolve_order) 5358 lp_set_ name_resolve_order(new_name_resolve_order);5359 5360 if (!tar_t ype&& !query_host && !service && !message) {5867 lp_set_cmdline("name resolve order", new_name_resolve_order); 5868 5869 if (!tar_to_process(tar_ctx) && !query_host && !service && !message) { 5361 5870 poptPrintUsage(pc, stderr, 0); 5362 5871 exit(1); … … 5364 5873 5365 5874 poptFreeContext(pc); 5875 popt_burn_cmdline_password(argc, argv); 5366 5876 5367 5877 DEBUG(3,("Client started (version %s).\n", samba_version_string())); … … 5370 5880 set_cmdline_auth_info_getpass(auth_info); 5371 5881 5372 if (tar_type) { 5882 max_protocol = lp_client_max_protocol(); 5883 5884 if (tar_to_process(tar_ctx)) { 5373 5885 if (cmdstr) 5374 5886 process_command_string(cmdstr); 5375 return do_tar_op(base_directory); 5376 } 5377 5378 if (query_host && *query_host) { 5887 rc = do_tar_op(base_directory); 5888 } else if (query_host && *query_host) { 5379 5889 char *qhost = query_host; 5380 5890 char *slash; … … 5394 5904 } 5395 5905 5396 return do_host_query(qhost); 5397 } 5398 5399 if (message) { 5400 return do_message_op(auth_info); 5401 } 5402 5403 if (process(base_directory)) { 5404 return 1; 5906 rc = do_host_query(qhost); 5907 } else if (message) { 5908 rc = do_message_op(auth_info); 5909 } else if (process(base_directory)) { 5910 rc = 1; 5405 5911 } 5406 5912 -
vendor/current/source3/client/client_proto.h
r740 r988 27 27 struct file_info; 28 28 29 enum { 30 ATTR_UNSET, 31 ATTR_SET, 32 }; 33 29 34 /* The following definitions come from client/client.c */ 30 35 … … 32 37 const char *client_set_cur_dir(const char *newdir); 33 38 NTSTATUS do_list(const char *mask, 34 uint16 attribute,39 uint16_t attribute, 35 40 NTSTATUS (*fn)(struct cli_state *cli_state, struct file_info *, 36 41 const char *dir), 37 42 bool rec, 38 43 bool dirs); 44 int set_remote_attr(const char *filename, uint16_t new_attr, int mode); 39 45 int cmd_iosize(void); 40 41 /* The following definitions come from client/clitar.c */42 43 int cmd_block(void);44 int cmd_tarmode(void);45 int cmd_setmode(void);46 int cmd_tar(void);47 int process_tar(void);48 int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind);49 46 50 47 /* The following definitions come from client/dnsbrowse.c */ -
vendor/current/source3/client/clitar.c
r746 r988 1 1 /* 2 2 Unix SMB/CIFS implementation. 3 Tar Extensions 4 Copyright (C) Ricky Poulten 1995-1998 5 Copyright (C) Richard Sharpe 1998 3 Tar backup command extension 4 Copyright (C) Aurélien Aptel 2013 6 5 7 6 This program is free software; you can redistribute it and/or modify … … 18 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 18 */ 20 /* The following changes developed by Richard Sharpe for Canon Information 21 Systems Research Australia (CISRA) 22 23 1. Restore can now restore files with long file names 24 2. Save now saves directory information so that we can restore 25 directory creation times 26 3. tar now accepts both UNIX path names and DOS path names. I prefer 27 those lovely /'s to those UGLY \'s :-) 28 4. the files to exclude can be specified as a regular expression by adding 29 an r flag to the other tar flags. Eg: 30 31 -TcrX file.tar "*.(obj|exe)" 32 33 will skip all .obj and .exe files 34 */ 35 19 20 /** 21 * # General overview of the tar extension 22 * 23 * All tar_xxx() functions work on a `struct tar` which store most of 24 * the context of the backup process. 25 * 26 * The current tar context can be accessed via the global variable 27 * `tar_ctx`. It's publicly exported as an opaque handle via 28 * tar_get_ctx(). 29 * 30 * A tar context is first configured through tar_parse_args() which 31 * can be called from either the CLI (in client.c) or the interactive 32 * session (via the cmd_tar() callback). 33 * 34 * Once the configuration is done (successfully), the context is ready 35 * for processing and tar_to_process() returns true. 36 * 37 * The next step is to call tar_process() which dispatch the 38 * processing to either tar_create() or tar_extract(), depending on 39 * the context. 40 * 41 * ## Archive creation 42 * 43 * tar_create() creates an archive using the libarchive API then 44 * 45 * - iterates on the requested paths if the context is in inclusion 46 * mode with tar_create_from_list() 47 * 48 * - or iterates on the whole share (starting from the current dir) if 49 * in exclusion mode or if no specific path were requested 50 * 51 * The do_list() function from client.c is used to list recursively 52 * the share. In particular it takes a DOS path mask (eg. \mydir\*) 53 * and a callback function which will be called with each file name 54 * and attributes. The tar callback function is get_file_callback(). 55 * 56 * The callback function checks whether the file should be skipped 57 * according the the configuration via tar_create_skip_path(). If it's 58 * not skipped it's downloaded and written to the archive in 59 * tar_get_file(). 60 * 61 * ## Archive extraction 62 * 63 * tar_extract() opens the archive and iterates on each file in 64 * it. For each file tar_extract_skip_path() checks whether it should 65 * be skipped according to the config. If it's not skipped it's 66 * uploaded on the server in tar_send_file(). 67 */ 36 68 37 69 #include "includes.h" 38 70 #include "system/filesys.h" 39 #include "clitar.h"40 71 #include "client/client_proto.h" 72 #include "client/clitar_proto.h" 41 73 #include "libsmb/libsmb.h" 42 74 43 static int clipfind(char **aret, int ret, char *tok); 44 45 typedef struct file_info_struct file_info2; 46 47 struct file_info_struct { 48 SMB_OFF_T size; 49 uint16 mode; 50 uid_t uid; 51 gid_t gid; 52 /* These times are normally kept in GMT */ 53 struct timespec mtime_ts; 54 struct timespec atime_ts; 55 struct timespec ctime_ts; 56 char *name; /* This is dynamically allocated */ 57 file_info2 *next, *prev; /* Used in the stack ... */ 75 #ifdef HAVE_LIBARCHIVE 76 77 #include <archive.h> 78 #include <archive_entry.h> 79 80 /* prepend module name and line number to debug messages */ 81 #define DBG(a, b) (DEBUG(a, ("tar:%-4d ", __LINE__)), DEBUG(a, b)) 82 83 /* preprocessor magic to stringify __LINE__ (int) */ 84 #define STR1(x) #x 85 #define STR2(x) STR1(x) 86 87 /** 88 * Number of byte in a block unit. 89 */ 90 #define TAR_BLOCK_UNIT 512 91 92 /** 93 * Default tar block size in TAR_BLOCK_UNIT. 94 */ 95 #define TAR_DEFAULT_BLOCK_SIZE 20 96 97 /** 98 * Maximum value for the blocksize field 99 */ 100 #define TAR_MAX_BLOCK_SIZE 0xffff 101 102 /** 103 * Size of the buffer used when downloading a file 104 */ 105 #define TAR_CLI_READ_SIZE 0xff00 106 107 #define TAR_DO_LIST_ATTR (FILE_ATTRIBUTE_DIRECTORY \ 108 | FILE_ATTRIBUTE_SYSTEM \ 109 | FILE_ATTRIBUTE_HIDDEN) 110 111 112 enum tar_operation { 113 TAR_NO_OPERATION, 114 TAR_CREATE, /* c flag */ 115 TAR_EXTRACT, /* x flag */ 58 116 }; 59 117 60 typedef struct { 61 file_info2 *top; 62 int items; 63 } stack; 64 65 #define SEPARATORS " \t\n\r" 66 extern time_t newer_than; 67 extern struct cli_state *cli; 68 69 /* These defines are for the do_setrattr routine, to indicate 70 * setting and reseting of file attributes in the function call */ 71 #define ATTRSET 1 72 #define ATTRRESET 0 73 74 static uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; 75 76 #ifndef CLIENT_TIMEOUT 77 #define CLIENT_TIMEOUT (30*1000) 78 #endif 79 80 static char *tarbuf, *buffer_p; 81 static int tp, ntarf, tbufsiz; 82 static double ttarf; 83 /* Incremental mode */ 84 static bool tar_inc=False; 85 /* Reset archive bit */ 86 static bool tar_reset=False; 87 /* Include / exclude mode (true=include, false=exclude) */ 88 static bool tar_excl=True; 89 /* use regular expressions for search on file names */ 90 static bool tar_re_search=False; 91 /* Do not dump anything, just calculate sizes */ 92 static bool dry_run=False; 93 /* Dump files with System attribute */ 94 static bool tar_system=True; 95 /* Dump files with Hidden attribute */ 96 static bool tar_hidden=True; 97 /* Be noisy - make a catalogue */ 98 static bool tar_noisy=True; 99 static bool tar_real_noisy=False; /* Don't want to be really noisy by default */ 100 101 char tar_type='\0'; 102 static char **cliplist=NULL; 103 static int clipn=0; 104 static bool must_free_cliplist = False; 105 extern const char *cmd_ptr; 106 107 extern bool lowercase; 108 extern uint16 cnum; 109 extern bool readbraw_supported; 110 extern int max_xmit; 111 extern int get_total_time_ms; 112 extern int get_total_size; 113 114 static int blocksize=20; 115 static int tarhandle; 116 117 static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime, 118 const char *amode, unsigned char ftype); 119 static NTSTATUS do_atar(const char *rname_in, char *lname, 120 struct file_info *finfo1); 121 static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo, 122 const char *dir); 123 static void oct_it(uint64_t value, int ndgs, char *p); 124 static void fixtarname(char *tptr, const char *fp, size_t l); 125 static int dotarbuf(int f, char *b, int n); 126 static void dozerobuf(int f, int n); 127 static void dotareof(int f); 128 static void initarbuf(void); 129 130 /* restore functions */ 131 static long readtarheader(union hblock *hb, file_info2 *finfo, const char *prefix); 132 static long unoct(char *p, int ndgs); 133 static void do_tarput(void); 134 static void unfixtarname(char *tptr, char *fp, int l, bool first); 135 136 /* 137 * tar specific utitlities 138 */ 139 140 /******************************************************************* 141 Create a string of size size+1 (for the null) 142 *******************************************************************/ 143 144 static char *string_create_s(int size) 145 { 146 char *tmp; 147 148 tmp = (char *)SMB_MALLOC(size+1); 149 150 if (tmp == NULL) { 151 DEBUG(0, ("Out of memory in string_create_s\n")); 152 } 153 154 return(tmp); 155 } 156 157 /**************************************************************************** 158 Write a tar header to buffer 159 ****************************************************************************/ 160 161 static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime, 162 const char *amode, unsigned char ftype) 163 { 164 union hblock hb; 165 int i, chk, l; 166 char *jp; 167 168 DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname)); 169 170 memset(hb.dummy, 0, sizeof(hb.dummy)); 171 172 l=strlen(aname); 173 /* We will be prepending a '.' in fixtarheader so use +2 to 174 * take care of the . and terminating zero. JRA. 175 */ 176 if (l+2 >= NAMSIZ) { 177 /* write a GNU tar style long header */ 178 char *b; 179 b = (char *)SMB_MALLOC(l+TBLOCK+100); 180 if (!b) { 181 DEBUG(0,("out of memory\n")); 182 exit(1); 183 } 184 writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L'); 185 memset(b, 0, l+TBLOCK+100); 186 fixtarname(b, aname, l+2); 187 i = strlen(b)+1; 188 DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b))); 189 dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1)); 190 SAFE_FREE(b); 191 } 192 193 fixtarname(hb.dbuf.name, aname, (l+2 >= NAMSIZ) ? NAMSIZ : l + 2); 194 195 if (lowercase) 196 strlower_m(hb.dbuf.name); 197 198 /* write out a "standard" tar format header */ 199 200 hb.dbuf.name[NAMSIZ-1]='\0'; 201 safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1); 202 oct_it((uint64_t)0, 8, hb.dbuf.uid); 203 oct_it((uint64_t)0, 8, hb.dbuf.gid); 204 oct_it((uint64_t) size, 13, hb.dbuf.size); 205 if (size > (uint64_t)077777777777LL) { 206 /* This is a non-POSIX compatible extention to store files 207 greater than 8GB. */ 208 209 memset(hb.dbuf.size, 0, 4); 210 hb.dbuf.size[0]=128; 211 for (i = 8; i; i--) { 212 hb.dbuf.size[i+3] = size & 0xff; 213 size >>= 8; 214 } 215 } 216 oct_it((uint64_t) mtime, 13, hb.dbuf.mtime); 217 memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum)); 218 memset(hb.dbuf.linkname, 0, NAMSIZ); 219 hb.dbuf.linkflag=ftype; 220 221 for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) 222 chk+=(0xFF & *jp++); 223 224 oct_it((uint64_t) chk, 8, hb.dbuf.chksum); 225 hb.dbuf.chksum[6] = '\0'; 226 227 (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy)); 228 } 229 230 /**************************************************************************** 231 Read a tar header into a hblock structure, and validate 232 ***************************************************************************/ 233 234 static long readtarheader(union hblock *hb, file_info2 *finfo, const char *prefix) 235 { 236 long chk, fchk; 118 enum tar_selection { 119 TAR_NO_SELECTION, 120 TAR_INCLUDE, /* I and F flag, default */ 121 TAR_EXCLUDE, /* X flag */ 122 }; 123 124 struct tar { 125 TALLOC_CTX *talloc_ctx; 126 127 /* in state that needs/can be processed? */ 128 bool to_process; 129 130 /* flags */ 131 struct tar_mode { 132 enum tar_operation operation; /* create, extract */ 133 enum tar_selection selection; /* include, exclude */ 134 int blocksize; /* size in TAR_BLOCK_UNIT of a tar file block */ 135 bool hidden; /* backup hidden file? */ 136 bool system; /* backup system file? */ 137 bool incremental; /* backup _only_ archived file? */ 138 bool reset; /* unset archive bit? */ 139 bool dry; /* don't write tar file? */ 140 bool regex; /* XXX: never actually using regex... */ 141 bool verbose; /* XXX: ignored */ 142 } mode; 143 144 /* nb of bytes received */ 145 uint64_t total_size; 146 147 /* path to tar archive name */ 148 char *tar_path; 149 150 /* list of path to include or exclude */ 151 char **path_list; 152 int path_list_size; 153 154 /* archive handle */ 155 struct archive *archive; 156 }; 157 158 /** 159 * Global context imported in client.c when needed. 160 * 161 * Default options. 162 */ 163 struct tar tar_ctx = { 164 .mode.selection = TAR_INCLUDE, 165 .mode.blocksize = TAR_DEFAULT_BLOCK_SIZE, 166 .mode.hidden = true, 167 .mode.system = true, 168 .mode.incremental = false, 169 .mode.reset = false, 170 .mode.dry = false, 171 .mode.regex = false, 172 .mode.verbose = false, 173 }; 174 175 /* tar, local function */ 176 static int tar_create(struct tar* t); 177 static int tar_create_from_list(struct tar *t); 178 static int tar_extract(struct tar *t); 179 static int tar_read_inclusion_file(struct tar *t, const char* filename); 180 static int tar_send_file(struct tar *t, struct archive_entry *entry); 181 static int tar_set_blocksize(struct tar *t, int size); 182 static int tar_set_newer_than(struct tar *t, const char *filename); 183 static NTSTATUS tar_add_selection_path(struct tar *t, const char *path); 184 static void tar_dump(struct tar *t); 185 static NTSTATUS tar_extract_skip_path(struct tar *t, 186 struct archive_entry *entry, 187 bool *_skip); 188 static TALLOC_CTX *tar_reset_mem_context(struct tar *t); 189 static void tar_free_mem_context(struct tar *t); 190 static NTSTATUS tar_create_skip_path(struct tar *t, 191 const char *fullpath, 192 const struct file_info *finfo, 193 bool *_skip); 194 195 static NTSTATUS tar_path_in_list(struct tar *t, const char *path, 196 bool reverse, bool *_is_in_list); 197 198 static int tar_get_file(struct tar *t, 199 const char *full_dos_path, 200 struct file_info *finfo); 201 202 static NTSTATUS get_file_callback(struct cli_state *cli, 203 struct file_info *finfo, 204 const char *dir); 205 206 /* utilities */ 207 static char *fix_unix_path(char *path, bool removeprefix); 208 static NTSTATUS path_base_name(TALLOC_CTX *ctx, const char *path, char **_base); 209 static const char* skip_useless_char_in_path(const char *p); 210 static int make_remote_path(const char *full_path); 211 static int max_token (const char *str); 212 static NTSTATUS is_subpath(const char *sub, const char *full, 213 bool *_subpath_match); 214 215 /** 216 * tar_get_ctx - retrieve global tar context handle 217 */ 218 struct tar *tar_get_ctx() 219 { 220 return &tar_ctx; 221 } 222 223 /** 224 * cmd_block - interactive command to change tar blocksize 225 * 226 * Read a size from the client command line and update the current 227 * blocksize. 228 */ 229 int cmd_block(void) 230 { 231 /* XXX: from client.c */ 232 const extern char *cmd_ptr; 233 char *buf; 234 int err = 0; 235 bool ok; 236 TALLOC_CTX *ctx = talloc_new(NULL); 237 if (ctx == NULL) { 238 return 1; 239 } 240 241 ok = next_token_talloc(ctx, &cmd_ptr, &buf, NULL); 242 if (!ok) { 243 DBG(0, ("blocksize <n>\n")); 244 err = 1; 245 goto out; 246 } 247 248 ok = tar_set_blocksize(&tar_ctx, atoi(buf)); 249 if (ok) { 250 DBG(0, ("invalid blocksize\n")); 251 err = 1; 252 goto out; 253 } 254 255 DBG(2, ("blocksize is now %d\n", tar_ctx.mode.blocksize)); 256 257 out: 258 talloc_free(ctx); 259 return err; 260 } 261 262 /** 263 * cmd_tarmode - interactive command to change tar behaviour 264 * 265 * Read one or more modes from the client command line and update the 266 * current tar mode. 267 */ 268 int cmd_tarmode(void) 269 { 270 const extern char *cmd_ptr; 271 char *buf; 237 272 int i; 238 char *jp; 239 240 /* 241 * read in a "standard" tar format header - we're not that interested 242 * in that many fields, though 243 */ 244 245 /* check the checksum */ 246 for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) 247 chk+=(0xFF & *jp++); 248 249 if (chk == 0) 250 return chk; 251 252 /* compensate for blanks in chksum header */ 253 for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;) 254 chk-=(0xFF & *jp++); 255 256 chk += ' ' * sizeof(hb->dbuf.chksum); 257 258 fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum)); 259 260 DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n", 261 chk, fchk, hb->dbuf.chksum)); 262 263 if (fchk != chk) { 264 DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk)); 265 dump_data(5, (uint8 *)hb - TBLOCK, TBLOCK *3); 266 return -1; 267 } 268 269 if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) { 270 DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name)); 271 return(-1); 272 } 273 274 safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3); 275 276 /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */ 277 unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name, 278 strlen(hb->dbuf.name) + 1, True); 279 280 /* can't handle some links at present */ 281 if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) { 282 if (hb->dbuf.linkflag == 0) { 283 DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n", 284 finfo->name)); 285 } else { 286 if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */ 287 /* Do nothing here at the moment. do_tarput will handle this 288 as long as the longlink gets back to it, as it has to advance 289 the buffer pointer, etc */ 290 } else { 291 DEBUG(0, ("this tar file appears to contain some kind \ 292 of link other than a GNUtar Longlink - ignoring\n")); 293 return -2; 294 } 295 } 296 } 297 298 if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) || 299 (*(finfo->name+strlen(finfo->name)-1) == '\\')) { 300 finfo->mode=FILE_ATTRIBUTE_DIRECTORY; 301 } else { 302 finfo->mode=0; /* we don't care about mode at the moment, we'll 303 * just make it a regular file */ 304 } 305 306 /* 307 * Bug fix by richard@sj.co.uk 308 * 309 * REC: restore times correctly (as does tar) 310 * We only get the modification time of the file; set the creation time 311 * from the mod. time, and the access time to current time 312 */ 313 finfo->mtime_ts = finfo->ctime_ts = 314 convert_time_t_to_timespec((time_t)strtol(hb->dbuf.mtime, NULL, 8)); 315 finfo->atime_ts = convert_time_t_to_timespec(time(NULL)); 316 if ((hb->dbuf.size[0] & 0xff) == 0x80) { 317 /* This is a non-POSIX compatible extention to extract files 318 greater than 8GB. */ 319 finfo->size = 0; 320 for (i = 0; i < 8; i++) { 321 finfo->size <<= 8; 322 finfo->size |= hb->dbuf.size[i+4] & 0xff; 323 } 324 } else { 325 finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size)); 326 } 327 328 return True; 329 } 330 331 /**************************************************************************** 332 Write out the tar buffer to tape or wherever 333 ****************************************************************************/ 334 335 static int dotarbuf(int f, char *b, int n) 336 { 337 int fail=1, writ=n; 338 339 if (dry_run) { 340 return writ; 341 } 342 /* This routine and the next one should be the only ones that do write()s */ 343 if (tp + n >= tbufsiz) { 344 int diff; 345 346 diff=tbufsiz-tp; 347 memcpy(tarbuf + tp, b, diff); 348 fail=fail && (1+sys_write(f, tarbuf, tbufsiz)); 349 n-=diff; 350 b+=diff; 351 tp=0; 352 353 while (n >= tbufsiz) { 354 fail=fail && (1 + sys_write(f, b, tbufsiz)); 355 n-=tbufsiz; 356 b+=tbufsiz; 357 } 358 } 359 360 if (n>0) { 361 memcpy(tarbuf+tp, b, n); 362 tp+=n; 363 } 364 365 return(fail ? writ : 0); 366 } 367 368 /**************************************************************************** 369 Write zeros to buffer / tape 370 ****************************************************************************/ 371 372 static void dozerobuf(int f, int n) 373 { 374 /* short routine just to write out n zeros to buffer - 375 * used to round files to nearest block 376 * and to do tar EOFs */ 377 378 if (dry_run) 379 return; 380 381 if (n+tp >= tbufsiz) { 382 memset(tarbuf+tp, 0, tbufsiz-tp); 383 if (sys_write(f, tarbuf, tbufsiz) != tbufsiz) { 384 DEBUG(0, ("dozerobuf: sys_write fail\n")); 385 return; 386 } 387 memset(tarbuf, 0, (tp+=n-tbufsiz)); 388 } else { 389 memset(tarbuf+tp, 0, n); 390 tp+=n; 391 } 392 } 393 394 /**************************************************************************** 395 Malloc tape buffer 396 ****************************************************************************/ 397 398 static void initarbuf(void) 399 { 400 /* initialize tar buffer */ 401 tbufsiz=blocksize*TBLOCK; 402 tarbuf=(char *)SMB_MALLOC(tbufsiz); /* FIXME: We might not get the buffer */ 403 404 /* reset tar buffer pointer and tar file counter and total dumped */ 405 tp=0; ntarf=0; ttarf=0; 406 } 407 408 /**************************************************************************** 409 Write two zero blocks at end of file 410 ****************************************************************************/ 411 412 static void dotareof(int f) 413 { 414 SMB_STRUCT_STAT stbuf; 415 /* Two zero blocks at end of file, write out full buffer */ 416 417 if (dry_run) 418 return; 419 420 (void) dozerobuf(f, TBLOCK); 421 (void) dozerobuf(f, TBLOCK); 422 423 if (sys_fstat(f, &stbuf, false) == -1) { 424 DEBUG(0, ("Couldn't stat file handle\n")); 425 return; 426 } 427 428 /* Could be a pipe, in which case S_ISREG should fail, 429 * and we should write out at full size */ 430 if (tp > 0) { 431 size_t towrite = S_ISREG(stbuf.st_ex_mode) ? tp : tbufsiz; 432 if (sys_write(f, tarbuf, towrite) != towrite) { 433 DEBUG(0,("dotareof: sys_write fail\n")); 434 } 435 } 436 } 437 438 /**************************************************************************** 439 (Un)mangle DOS pathname, make nonabsolute 440 ****************************************************************************/ 441 442 static void fixtarname(char *tptr, const char *fp, size_t l) 443 { 444 /* add a '.' to start of file name, convert from ugly dos \'s in path 445 * to lovely unix /'s :-} */ 446 *tptr++='.'; 447 l--; 448 449 StrnCpy(tptr, fp, l-1); 450 string_replace(tptr, '\\', '/'); 451 } 452 453 /**************************************************************************** 454 Convert from decimal to octal string 455 ****************************************************************************/ 456 457 static void oct_it (uint64_t value, int ndgs, char *p) 458 { 459 /* Converts long to octal string, pads with leading zeros */ 460 461 /* skip final null, but do final space */ 462 --ndgs; 463 p[--ndgs] = ' '; 464 465 /* Loop does at least one digit */ 466 do { 467 p[--ndgs] = '0' + (char) (value & 7); 468 value >>= 3; 469 } while (ndgs > 0 && value != 0); 470 471 /* Do leading zeros */ 472 while (ndgs > 0) 473 p[--ndgs] = '0'; 474 } 475 476 /**************************************************************************** 477 Convert from octal string to long 478 ***************************************************************************/ 479 480 static long unoct(char *p, int ndgs) 481 { 482 long value=0; 483 /* Converts octal string to long, ignoring any non-digit */ 484 485 while (--ndgs) { 486 if (isdigit((int)*p)) 487 value = (value << 3) | (long) (*p - '0'); 488 489 p++; 490 } 491 492 return value; 493 } 494 495 /**************************************************************************** 496 Compare two strings in a slash insensitive way, allowing s1 to match s2 497 if s1 is an "initial" string (up to directory marker). Thus, if s2 is 498 a file in any subdirectory of s1, declare a match. 499 ***************************************************************************/ 500 501 static int strslashcmp(char *s1, char *s2) 502 { 503 char *s1_0=s1; 504 505 while(*s1 && *s2 && (*s1 == *s2 || tolower_m(*s1) == tolower_m(*s2) || 506 (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) { 507 s1++; s2++; 508 } 509 510 /* if s1 has a trailing slash, it compared equal, so s1 is an "initial" 511 string of s2. 512 */ 513 if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) 514 return 0; 515 516 /* ignore trailing slash on s1 */ 517 if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) 518 return 0; 519 520 /* check for s1 is an "initial" string of s2 */ 521 if ((*s2 == '/' || *s2 == '\\') && !*s1) 522 return 0; 523 524 return *s1-*s2; 525 } 526 527 /**************************************************************************** 528 Ensure a remote path exists (make if necessary) 529 ***************************************************************************/ 530 531 static bool ensurepath(const char *fname) 532 { 533 /* *must* be called with buffer ready malloc'ed */ 534 /* ensures path exists */ 535 536 char *partpath, *ffname; 537 const char *p=fname; 538 char *basehack; 539 char *saveptr; 540 541 DEBUG(5, ( "Ensurepath called with: %s\n", fname)); 542 543 partpath = string_create_s(strlen(fname)); 544 ffname = string_create_s(strlen(fname)); 545 546 if ((partpath == NULL) || (ffname == NULL)){ 547 DEBUG(0, ("Out of memory in ensurepath: %s\n", fname)); 548 SAFE_FREE(partpath); 549 SAFE_FREE(ffname); 550 return(False); 551 } 552 553 *partpath = 0; 554 555 /* fname copied to ffname so can strtok_r */ 556 557 safe_strcpy(ffname, fname, strlen(fname)); 558 559 /* do a `basename' on ffname, so don't try and make file name directory */ 560 if ((basehack=strrchr_m(ffname, '\\')) == NULL) { 561 SAFE_FREE(partpath); 562 SAFE_FREE(ffname); 563 return True; 564 } else { 565 *basehack='\0'; 566 } 567 568 p=strtok_r(ffname, "\\", &saveptr); 569 570 while (p) { 571 safe_strcat(partpath, p, strlen(fname) + 1); 572 573 if (!NT_STATUS_IS_OK(cli_chkpath(cli, partpath))) { 574 if (!NT_STATUS_IS_OK(cli_mkdir(cli, partpath))) { 575 SAFE_FREE(partpath); 576 SAFE_FREE(ffname); 577 DEBUG(0, ("Error mkdir %s\n", cli_errstr(cli))); 578 return False; 579 } else { 580 DEBUG(3, ("mkdirhiering %s\n", partpath)); 581 } 582 } 583 584 safe_strcat(partpath, "\\", strlen(fname) + 1); 585 p = strtok_r(NULL, "/\\", &saveptr); 586 } 587 588 SAFE_FREE(partpath); 589 SAFE_FREE(ffname); 590 return True; 591 } 592 593 static int padit(char *buf, uint64_t bufsize, uint64_t padsize) 594 { 595 int berr= 0; 596 int bytestowrite; 597 598 DEBUG(5, ("Padding with %0.f zeros\n", (double)padsize)); 599 memset(buf, 0, (size_t)bufsize); 600 while( !berr && padsize > 0 ) { 601 bytestowrite= (int)MIN(bufsize, padsize); 602 berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite; 603 padsize -= bytestowrite; 604 } 605 606 return berr; 607 } 608 609 static void do_setrattr(char *name, uint16 attr, int set) 610 { 611 uint16 oldattr; 612 613 if (!NT_STATUS_IS_OK(cli_getatr(cli, name, &oldattr, NULL, NULL))) { 614 return; 615 } 616 617 if (set == ATTRSET) { 618 attr |= oldattr; 619 } else { 620 attr = oldattr & ~attr; 621 } 622 623 if (!NT_STATUS_IS_OK(cli_setatr(cli, name, attr, 0))) { 624 DEBUG(1,("setatr failed: %s\n", cli_errstr(cli))); 625 } 626 } 627 628 /**************************************************************************** 629 append one remote file to the tar file 630 ***************************************************************************/ 631 632 static NTSTATUS do_atar(const char *rname_in, char *lname, 633 struct file_info *finfo1) 634 { 635 uint16_t fnum = (uint16_t)-1; 636 uint64_t nread=0; 637 char ftype; 638 file_info2 finfo; 639 bool shallitime=True; 640 char *data = NULL; 641 int read_size = 65520; 642 int datalen=0; 643 char *rname = NULL; 644 TALLOC_CTX *ctx = talloc_stackframe(); 645 NTSTATUS status = NT_STATUS_OK; 646 struct timespec tp_start; 647 648 clock_gettime_mono(&tp_start); 649 650 data = SMB_MALLOC_ARRAY(char, read_size); 651 if (!data) { 652 DEBUG(0,("do_atar: out of memory.\n")); 653 status = NT_STATUS_NO_MEMORY; 654 goto cleanup; 655 } 656 657 ftype = '0'; /* An ordinary file ... */ 658 659 ZERO_STRUCT(finfo); 660 661 finfo.size = finfo1 -> size; 662 finfo.mode = finfo1 -> mode; 663 finfo.uid = finfo1 -> uid; 664 finfo.gid = finfo1 -> gid; 665 finfo.mtime_ts = finfo1 -> mtime_ts; 666 finfo.atime_ts = finfo1 -> atime_ts; 667 finfo.ctime_ts = finfo1 -> ctime_ts; 668 669 if (dry_run) { 670 DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo1->name, 671 (double)finfo.size)); 672 shallitime=0; 673 ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); 674 ntarf++; 675 goto cleanup; 676 } 677 678 rname = clean_name(ctx, rname_in); 679 if (!rname) { 680 status = NT_STATUS_NO_MEMORY; 681 goto cleanup; 682 } 683 684 status = cli_open(cli, rname, O_RDONLY, DENY_NONE, &fnum); 685 if (!NT_STATUS_IS_OK(status)) { 686 DEBUG(0,("%s opening remote file %s (%s)\n", 687 cli_errstr(cli),rname, client_get_cur_dir())); 688 goto cleanup; 689 } 690 691 finfo.name = string_create_s(strlen(rname)); 692 if (finfo.name == NULL) { 693 DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n")); 694 status = NT_STATUS_NO_MEMORY; 695 goto cleanup; 696 } 697 698 safe_strcpy(finfo.name,rname, strlen(rname)); 699 700 DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode)); 701 702 if (tar_inc && !(finfo.mode & FILE_ATTRIBUTE_ARCHIVE)) { 703 DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name)); 704 shallitime=0; 705 } else if (!tar_system && (finfo.mode & FILE_ATTRIBUTE_SYSTEM)) { 706 DEBUG(4, ("skipping %s - system bit is set\n", finfo.name)); 707 shallitime=0; 708 } else if (!tar_hidden && (finfo.mode & FILE_ATTRIBUTE_HIDDEN)) { 709 DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name)); 710 shallitime=0; 711 } else { 712 bool wrote_tar_header = False; 713 714 DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s", 715 finfo.name, (double)finfo.size, lname)); 716 717 do { 718 719 DEBUG(3,("nread=%.0f\n",(double)nread)); 720 721 datalen = cli_read(cli, fnum, data, nread, read_size); 722 723 if (datalen == -1) { 724 DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli))); 725 status = cli_nt_error(cli); 273 TALLOC_CTX *ctx; 274 275 struct { 276 const char *cmd; 277 bool *p; 278 bool value; 279 } table[] = { 280 {"full", &tar_ctx.mode.incremental, false}, 281 {"inc", &tar_ctx.mode.incremental, true }, 282 {"reset", &tar_ctx.mode.reset, true }, 283 {"noreset", &tar_ctx.mode.reset, false}, 284 {"system", &tar_ctx.mode.system, true }, 285 {"nosystem", &tar_ctx.mode.system, false}, 286 {"hidden", &tar_ctx.mode.hidden, true }, 287 {"nohidden", &tar_ctx.mode.hidden, false}, 288 {"verbose", &tar_ctx.mode.verbose, true }, 289 {"noquiet", &tar_ctx.mode.verbose, true }, 290 {"quiet", &tar_ctx.mode.verbose, false}, 291 {"noverbose", &tar_ctx.mode.verbose, false}, 292 }; 293 294 ctx = talloc_new(NULL); 295 if (ctx == NULL) { 296 return 1; 297 } 298 299 while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL)) { 300 for (i = 0; i < ARRAY_SIZE(table); i++) { 301 if (strequal(table[i].cmd, buf)) { 302 *table[i].p = table[i].value; 726 303 break; 727 304 } 728 729 nread += datalen; 730 731 /* Only if the first read succeeds, write out the tar header. */ 732 if (!wrote_tar_header) { 733 /* write a tar header, don't bother with mode - just set to 100644 */ 734 writetarheader(tarhandle, rname, finfo.size, 735 finfo.mtime_ts.tv_sec, "100644 \0", ftype); 736 wrote_tar_header = True; 305 } 306 307 if (i == ARRAY_SIZE(table)) 308 DBG(0, ("tarmode: unrecognised option %s\n", buf)); 309 } 310 311 DBG(0, ("tarmode is now %s, %s, %s, %s, %s\n", 312 tar_ctx.mode.incremental ? "incremental" : "full", 313 tar_ctx.mode.system ? "system" : "nosystem", 314 tar_ctx.mode.hidden ? "hidden" : "nohidden", 315 tar_ctx.mode.reset ? "reset" : "noreset", 316 tar_ctx.mode.verbose ? "verbose" : "quiet")); 317 318 talloc_free(ctx); 319 return 0; 320 } 321 322 /** 323 * cmd_tar - interactive command to start a tar backup/restoration 324 * 325 * Check presence of argument, parse them and handle the request. 326 */ 327 int cmd_tar(void) 328 { 329 const extern char *cmd_ptr; 330 const char *flag; 331 const char **val; 332 char *buf; 333 int maxtok = max_token(cmd_ptr); 334 int i = 0; 335 int err = 0; 336 bool ok; 337 int rc; 338 TALLOC_CTX *ctx = talloc_new(NULL); 339 if (ctx == NULL) { 340 return 1; 341 } 342 343 ok = next_token_talloc(ctx, &cmd_ptr, &buf, NULL); 344 if (!ok) { 345 DBG(0, ("tar <c|x>[IXFbganN] [options] <tar file> [path list]\n")); 346 err = 1; 347 goto out; 348 } 349 350 flag = buf; 351 val = talloc_array(ctx, const char *, maxtok); 352 if (val == NULL) { 353 err = 1; 354 goto out; 355 } 356 357 while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL)) { 358 val[i++] = buf; 359 } 360 361 rc = tar_parse_args(&tar_ctx, flag, val, i); 362 if (rc != 0) { 363 DBG(0, ("parse_args failed\n")); 364 err = 1; 365 goto out; 366 } 367 368 rc = tar_process(&tar_ctx); 369 if (rc != 0) { 370 DBG(0, ("tar_process failed\n")); 371 err = 1; 372 goto out; 373 } 374 375 out: 376 talloc_free(ctx); 377 return err; 378 } 379 380 381 /** 382 * tar_parse_args - parse and set tar command line arguments 383 * @flag: string pointing to tar options 384 * @val: number of tar arguments 385 * @valsize: table of arguments after the flags (number of element in val) 386 * 387 * tar arguments work in a weird way. For each flag f that takes a 388 * value v, the user is supposed to type: 389 * 390 * on the CLI: 391 * -Tf1f2f3 v1 v2 v3 TARFILE PATHS... 392 * 393 * in the interactive session: 394 * tar f1f2f3 v1 v2 v3 TARFILE PATHS... 395 * 396 * @flag has only flags (eg. "f1f2f3") and @val has the arguments 397 * (values) following them (eg. ["v1", "v2", "v3", "TARFILE", "PATH1", 398 * "PATH2"]). 399 * 400 * There are only 2 flags that take an arg: b and N. The other flags 401 * just change the semantic of PATH or TARFILE. 402 * 403 * PATH can be a list of included/excluded paths, the path to a file 404 * containing a list of included/excluded paths to use (F flag). If no 405 * PATH is provided, the whole share is used (/). 406 */ 407 int tar_parse_args(struct tar* t, 408 const char *flag, 409 const char **val, 410 int valsize) 411 { 412 TALLOC_CTX *ctx; 413 bool do_read_list = false; 414 /* index of next value to use */ 415 int ival = 0; 416 int rc; 417 418 if (t == NULL) { 419 DBG(0, ("Invalid tar context\n")); 420 return 1; 421 } 422 423 ctx = tar_reset_mem_context(t); 424 if (ctx == NULL) { 425 return 1; 426 } 427 /* 428 * Reset back some options - could be from interactive version 429 * all other modes are left as they are 430 */ 431 t->mode.operation = TAR_NO_OPERATION; 432 t->mode.selection = TAR_NO_SELECTION; 433 t->mode.dry = false; 434 t->to_process = false; 435 t->total_size = 0; 436 437 while (flag[0] != '\0') { 438 switch(flag[0]) { 439 /* operation */ 440 case 'c': 441 if (t->mode.operation != TAR_NO_OPERATION) { 442 printf("Tar must be followed by only one of c or x.\n"); 443 return 1; 737 444 } 738 739 /* if file size has increased since we made file size query, truncate 740 read so tar header for this file will be correct. 741 */ 742 743 if (nread > finfo.size) { 744 datalen -= nread - finfo.size; 745 DEBUG(0,("File size change - truncating %s to %.0f bytes\n", 746 finfo.name, (double)finfo.size)); 445 t->mode.operation = TAR_CREATE; 446 break; 447 case 'x': 448 if (t->mode.operation != TAR_NO_OPERATION) { 449 printf("Tar must be followed by only one of c or x.\n"); 450 return 1; 747 451 } 748 749 /* add received bits of file to buffer - dotarbuf will750 * write out in 512 byte intervals */ 751 752 if (dotarbuf(tarhandle,data,datalen) != datalen) {753 DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));754 status = map_nt_error_from_unix(errno);755 break;452 t->mode.operation = TAR_EXTRACT; 453 break; 454 455 /* selection */ 456 case 'I': 457 if (t->mode.selection != TAR_NO_SELECTION) { 458 DBG(0,("Only one of I,X,F must be specified\n")); 459 return 1; 756 460 } 757 758 if ( (datalen == 0) && (finfo.size != 0) ) { 759 status = NT_STATUS_UNSUCCESSFUL; 760 DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname)); 761 break; 461 t->mode.selection = TAR_INCLUDE; 462 break; 463 case 'X': 464 if (t->mode.selection != TAR_NO_SELECTION) { 465 DBG(0,("Only one of I,X,F must be specified\n")); 466 return 1; 762 467 } 763 764 datalen=0; 765 } while ( nread < finfo.size ); 766 767 if (wrote_tar_header) { 768 /* pad tar file with zero's if we couldn't get entire file */ 769 if (nread < finfo.size) { 770 DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", 771 (double)finfo.size, (int)nread)); 772 if (padit(data, (uint64_t)sizeof(data), finfo.size - nread)) { 773 status = map_nt_error_from_unix(errno); 774 DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); 775 } 468 t->mode.selection = TAR_EXCLUDE; 469 break; 470 case 'F': 471 if (t->mode.selection != TAR_NO_SELECTION) { 472 DBG(0,("Only one of I,X,F must be specified\n")); 473 return 1; 776 474 } 777 778 /* round tar file to nearest block */ 779 if (finfo.size % TBLOCK) 780 dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); 781 782 ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); 783 ntarf++; 475 t->mode.selection = TAR_INCLUDE; 476 do_read_list = true; 477 break; 478 479 /* blocksize */ 480 case 'b': 481 if (ival >= valsize) { 482 DBG(0, ("Option b must be followed by a blocksize\n")); 483 return 1; 484 } 485 486 if (tar_set_blocksize(t, atoi(val[ival]))) { 487 DBG(0, ("Option b must be followed by a valid blocksize\n")); 488 return 1; 489 } 490 491 ival++; 492 break; 493 494 /* incremental mode */ 495 case 'g': 496 t->mode.incremental = true; 497 break; 498 499 /* newer than */ 500 case 'N': 501 if (ival >= valsize) { 502 DBG(0, ("Option N must be followed by valid file name\n")); 503 return 1; 504 } 505 506 if (tar_set_newer_than(t, val[ival])) { 507 DBG(0,("Error setting newer-than time\n")); 508 return 1; 509 } 510 511 ival++; 512 break; 513 514 /* reset mode */ 515 case 'a': 516 t->mode.reset = true; 517 break; 518 519 /* verbose */ 520 case 'q': 521 t->mode.verbose = true; 522 break; 523 524 /* regex match */ 525 case 'r': 526 t->mode.regex = true; 527 break; 528 529 /* dry run mode */ 530 case 'n': 531 if (t->mode.operation != TAR_CREATE) { 532 DBG(0, ("n is only meaningful when creating a tar-file\n")); 533 return 1; 534 } 535 536 t->mode.dry = true; 537 DBG(0, ("dry_run set\n")); 538 break; 539 540 default: 541 DBG(0,("Unknown tar option\n")); 542 return 1; 543 } 544 545 flag++; 546 } 547 548 /* no selection given? default selection is include */ 549 if (t->mode.selection == TAR_NO_SELECTION) { 550 t->mode.selection = TAR_INCLUDE; 551 } 552 553 if (valsize - ival < 1) { 554 DBG(0, ("No tar file given.\n")); 555 return 1; 556 } 557 558 /* handle TARFILE */ 559 t->tar_path = talloc_strdup(ctx, val[ival]); 560 if (t->tar_path == NULL) { 561 return 1; 562 } 563 ival++; 564 565 /* 566 * Make sure that dbf points to stderr if we are using stdout for 567 * tar output 568 */ 569 if (t->mode.operation == TAR_CREATE && strequal(t->tar_path, "-")) { 570 setup_logging("smbclient", DEBUG_STDERR); 571 } 572 573 /* handle PATHs... */ 574 575 /* flag F -> read file list */ 576 if (do_read_list) { 577 if (valsize - ival != 1) { 578 DBG(0,("Option F must be followed by exactly one filename.\n")); 579 return 1; 580 } 581 582 rc = tar_read_inclusion_file(t, val[ival]); 583 if (rc != 0) { 584 return 1; 585 } 586 ival++; 587 /* otherwise store all the PATHs on the command line */ 588 } else { 589 int i; 590 for (i = ival; i < valsize; i++) { 591 NTSTATUS status; 592 status = tar_add_selection_path(t, val[i]); 593 if (!NT_STATUS_IS_OK(status)) { 594 return 1; 595 } 596 } 597 } 598 599 t->to_process = true; 600 tar_dump(t); 601 return 0; 602 } 603 604 /** 605 * tar_process - start processing archive 606 * 607 * The talloc context of the fields is freed at the end of the call. 608 */ 609 int tar_process(struct tar *t) 610 { 611 int rc = 0; 612 613 if (t == NULL) { 614 DBG(0, ("Invalid tar context\n")); 615 return 1; 616 } 617 618 switch(t->mode.operation) { 619 case TAR_EXTRACT: 620 rc = tar_extract(t); 621 break; 622 case TAR_CREATE: 623 rc = tar_create(t); 624 break; 625 default: 626 DBG(0, ("Invalid tar state\n")); 627 rc = 1; 628 } 629 630 t->to_process = false; 631 tar_free_mem_context(t); 632 DBG(5, ("tar_process done, err = %d\n", rc)); 633 return rc; 634 } 635 636 /** 637 * tar_create - create archive and fetch files 638 */ 639 static int tar_create(struct tar* t) 640 { 641 int r; 642 int err = 0; 643 NTSTATUS status; 644 const char *mask; 645 TALLOC_CTX *ctx = talloc_new(NULL); 646 if (ctx == NULL) { 647 return 1; 648 } 649 650 t->archive = archive_write_new(); 651 652 if (!t->mode.dry) { 653 const int bsize = t->mode.blocksize * TAR_BLOCK_UNIT; 654 r = archive_write_set_bytes_per_block(t->archive, bsize); 655 if (r != ARCHIVE_OK) { 656 DBG(0, ("Can't use a block size of %d bytes", bsize)); 657 err = 1; 658 goto out; 659 } 660 661 /* 662 * Use PAX restricted format which is not the most 663 * conservative choice but has useful extensions and is widely 664 * supported 665 */ 666 r = archive_write_set_format_pax_restricted(t->archive); 667 if (r != ARCHIVE_OK) { 668 DBG(0, ("Can't use pax restricted format: %s\n", 669 archive_error_string(t->archive))); 670 err = 1; 671 goto out; 672 } 673 674 if (strequal(t->tar_path, "-")) { 675 r = archive_write_open_fd(t->archive, STDOUT_FILENO); 784 676 } else { 785 DEBUG(4, ("skipping %s - initial read failed (file was locked ?)\n", finfo.name)); 786 shallitime=0; 677 r = archive_write_open_filename(t->archive, t->tar_path); 678 } 679 680 if (r != ARCHIVE_OK) { 681 DBG(0, ("Can't open %s: %s\n", t->tar_path, 682 archive_error_string(t->archive))); 683 err = 1; 684 goto out_close; 685 } 686 } 687 688 /* 689 * In inclusion mode, iterate on the inclusion list 690 */ 691 if (t->mode.selection == TAR_INCLUDE && t->path_list_size > 0) { 692 if (tar_create_from_list(t)) { 693 err = 1; 694 goto out_close; 695 } 696 } else { 697 mask = talloc_asprintf(ctx, "%s\\*", client_get_cur_dir()); 698 if (mask == NULL) { 699 err = 1; 700 goto out_close; 701 } 702 DBG(5, ("tar_process do_list with mask: %s\n", mask)); 703 status = do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true); 704 if (!NT_STATUS_IS_OK(status)) { 705 DBG(0, ("do_list fail %s\n", nt_errstr(status))); 706 err = 1; 707 goto out_close; 708 } 709 } 710 711 out_close: 712 DBG(0, ("Total bytes received: %" PRIu64 "\n", t->total_size)); 713 714 if (!t->mode.dry) { 715 r = archive_write_close(t->archive); 716 if (r != ARCHIVE_OK) { 717 DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); 718 err = 1; 719 goto out; 720 } 721 } 722 out: 723 #ifdef HAVE_ARCHIVE_READ_FREE 724 archive_write_free(t->archive); 725 #else 726 archive_write_finish(t->archive); 727 #endif 728 talloc_free(ctx); 729 return err; 730 } 731 732 /** 733 * tar_create_from_list - fetch from path list in include mode 734 */ 735 static int tar_create_from_list(struct tar *t) 736 { 737 int err = 0; 738 NTSTATUS status; 739 char *base; 740 const char *path, *mask, *start_dir; 741 int i; 742 TALLOC_CTX *ctx = talloc_new(NULL); 743 if (ctx == NULL) { 744 return 1; 745 } 746 747 start_dir = talloc_strdup(ctx, client_get_cur_dir()); 748 if (start_dir == NULL) { 749 err = 1; 750 goto out; 751 } 752 753 for (i = 0; i < t->path_list_size; i++) { 754 path = t->path_list[i]; 755 base = NULL; 756 status = path_base_name(ctx, path, &base); 757 if (!NT_STATUS_IS_OK(status)) { 758 err = 1; 759 goto out; 760 } 761 mask = talloc_asprintf(ctx, "%s\\%s", 762 client_get_cur_dir(), path); 763 if (mask == NULL) { 764 err = 1; 765 goto out; 766 } 767 768 DBG(5, ("incl. path='%s', base='%s', mask='%s'\n", 769 path, base ? base : "NULL", mask)); 770 771 if (base != NULL) { 772 base = talloc_asprintf(ctx, "%s%s\\", 773 client_get_cur_dir(), base); 774 if (base == NULL) { 775 err = 1; 776 goto out; 777 } 778 DBG(5, ("cd '%s' before do_list\n", base)); 779 client_set_cur_dir(base); 780 } 781 status = do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true); 782 if (base != NULL) { 783 client_set_cur_dir(start_dir); 784 } 785 if (!NT_STATUS_IS_OK(status)) { 786 DBG(0, ("do_list failed on %s (%s)\n", path, nt_errstr(status))); 787 err = 1; 788 goto out; 789 } 790 } 791 792 out: 793 talloc_free(ctx); 794 return err; 795 } 796 797 /** 798 * get_file_callback - do_list callback 799 * 800 * Callback for client.c do_list(). Called for each file found on the 801 * share matching do_list mask. Recursively call do_list() with itself 802 * as callback when the current file is a directory. 803 */ 804 static NTSTATUS get_file_callback(struct cli_state *cli, 805 struct file_info *finfo, 806 const char *dir) 807 { 808 NTSTATUS status = NT_STATUS_OK; 809 char *remote_name; 810 const char *initial_dir = client_get_cur_dir(); 811 bool skip = false; 812 int rc; 813 TALLOC_CTX *ctx = talloc_new(NULL); 814 if (ctx == NULL) { 815 return NT_STATUS_NO_MEMORY; 816 } 817 818 remote_name = talloc_asprintf(ctx, "%s%s", initial_dir, finfo->name); 819 if (remote_name == NULL) { 820 status = NT_STATUS_NO_MEMORY; 821 goto out; 822 } 823 824 if (strequal(finfo->name, "..") || strequal(finfo->name, ".")) { 825 goto out; 826 } 827 828 status = tar_create_skip_path(&tar_ctx, remote_name, finfo, &skip); 829 if (!NT_STATUS_IS_OK(status)) { 830 goto out; 831 } 832 833 if (skip) { 834 DBG(5, ("--- %s\n", remote_name)); 835 status = NT_STATUS_OK; 836 goto out; 837 } 838 839 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { 840 char *old_dir; 841 char *new_dir; 842 char *mask; 843 844 old_dir = talloc_strdup(ctx, initial_dir); 845 new_dir = talloc_asprintf(ctx, "%s%s\\", 846 initial_dir, finfo->name); 847 if ((old_dir == NULL) || (new_dir == NULL)) { 848 status = NT_STATUS_NO_MEMORY; 849 goto out; 850 } 851 mask = talloc_asprintf(ctx, "%s*", new_dir); 852 if (mask == NULL) { 853 status = NT_STATUS_NO_MEMORY; 854 goto out; 855 } 856 857 rc = tar_get_file(&tar_ctx, remote_name, finfo); 858 if (rc != 0) { 787 859 status = NT_STATUS_UNSUCCESSFUL; 788 } 789 } 790 791 cli_close(cli, fnum); 792 fnum = -1; 793 794 if (shallitime) { 795 struct timespec tp_end; 796 int this_time; 797 798 /* if shallitime is true then we didn't skip */ 799 if (tar_reset && !dry_run) 800 (void) do_setrattr(finfo.name, FILE_ATTRIBUTE_ARCHIVE, ATTRRESET); 801 802 clock_gettime_mono(&tp_end); 803 this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_nsec - tp_start.tv_nsec)/1000000; 804 get_total_time_ms += this_time; 805 get_total_size += finfo.size; 806 807 if (tar_noisy) { 808 DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n", 809 (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)), 810 finfo.name)); 811 } 812 813 /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */ 814 DEBUG(3,("(%g kb/s) (average %g kb/s)\n", 815 finfo.size / MAX(0.001, (1.024*this_time)), 816 get_total_size / MAX(0.001, (1.024*get_total_time_ms)))); 817 } 818 819 cleanup: 820 821 if (fnum != (uint16_t)-1) { 822 cli_close(cli, fnum); 823 fnum = -1; 824 } 825 TALLOC_FREE(ctx); 826 SAFE_FREE(data); 860 goto out; 861 } 862 863 client_set_cur_dir(new_dir); 864 do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true); 865 client_set_cur_dir(old_dir); 866 } else { 867 rc = tar_get_file(&tar_ctx, remote_name, finfo); 868 if (rc != 0) { 869 status = NT_STATUS_UNSUCCESSFUL; 870 goto out; 871 } 872 } 873 874 out: 875 talloc_free(ctx); 827 876 return status; 828 877 } 829 878 830 /**************************************************************************** 831 Append single file to tar file (or not) 832 ***************************************************************************/ 833 834 static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo, 835 const char *dir) 836 { 837 TALLOC_CTX *ctx = talloc_stackframe(); 879 /** 880 * tar_get_file - fetch a remote file to the local archive 881 * @full_dos_path: path to the file to fetch 882 * @finfo: attributes of the file to fetch 883 */ 884 static int tar_get_file(struct tar *t, 885 const char *full_dos_path, 886 struct file_info *finfo) 887 { 888 extern struct cli_state *cli; 889 NTSTATUS status; 890 struct archive_entry *entry; 891 char *full_unix_path; 892 char buf[TAR_CLI_READ_SIZE]; 893 size_t len; 894 uint64_t off = 0; 895 uint16_t remote_fd = (uint16_t)-1; 896 int err = 0, r; 897 const bool isdir = finfo->mode & FILE_ATTRIBUTE_DIRECTORY; 898 TALLOC_CTX *ctx = talloc_new(NULL); 899 if (ctx == NULL) { 900 return 1; 901 } 902 903 DBG(5, ("+++ %s\n", full_dos_path)); 904 905 t->total_size += finfo->size; 906 907 if (t->mode.dry) { 908 goto out; 909 } 910 911 if (t->mode.reset) { 912 /* ignore return value: server might not store DOS attributes */ 913 set_remote_attr(full_dos_path, FILE_ATTRIBUTE_ARCHIVE, ATTR_UNSET); 914 } 915 916 full_unix_path = talloc_asprintf(ctx, ".%s", full_dos_path); 917 if (full_unix_path == NULL) { 918 err = 1; 919 goto out; 920 } 921 string_replace(full_unix_path, '\\', '/'); 922 entry = archive_entry_new(); 923 archive_entry_copy_pathname(entry, full_unix_path); 924 archive_entry_set_filetype(entry, isdir ? AE_IFDIR : AE_IFREG); 925 archive_entry_set_atime(entry, 926 finfo->atime_ts.tv_sec, 927 finfo->atime_ts.tv_nsec); 928 archive_entry_set_mtime(entry, 929 finfo->mtime_ts.tv_sec, 930 finfo->mtime_ts.tv_nsec); 931 archive_entry_set_ctime(entry, 932 finfo->ctime_ts.tv_sec, 933 finfo->ctime_ts.tv_nsec); 934 archive_entry_set_perm(entry, isdir ? 0755 : 0644); 935 /* 936 * check if we can safely cast unsigned file size to libarchive 937 * signed size. Very unlikely problem (>9 exabyte file) 938 */ 939 if (finfo->size > INT64_MAX) { 940 DBG(0, ("Remote file %s too big\n", full_dos_path)); 941 goto out_entry; 942 } 943 944 archive_entry_set_size(entry, (int64_t)finfo->size); 945 946 r = archive_write_header(t->archive, entry); 947 if (r != ARCHIVE_OK) { 948 DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); 949 err = 1; 950 goto out_entry; 951 } 952 953 if (isdir) { 954 DBG(5, ("get_file skip dir %s\n", full_dos_path)); 955 goto out_entry; 956 } 957 958 status = cli_open(cli, full_dos_path, O_RDONLY, DENY_NONE, &remote_fd); 959 if (!NT_STATUS_IS_OK(status)) { 960 DBG(0,("%s opening remote file %s\n", 961 nt_errstr(status), full_dos_path)); 962 goto out_entry; 963 } 964 965 do { 966 status = cli_read(cli, remote_fd, buf, off, sizeof(buf), &len); 967 if (!NT_STATUS_IS_OK(status)) { 968 DBG(0,("Error reading file %s : %s\n", 969 full_dos_path, nt_errstr(status))); 970 err = 1; 971 goto out_close; 972 } 973 974 off += len; 975 976 r = archive_write_data(t->archive, buf, len); 977 if (r < 0) { 978 DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); 979 err = 1; 980 goto out_close; 981 } 982 983 } while (off < finfo->size); 984 985 out_close: 986 cli_close(cli, remote_fd); 987 988 out_entry: 989 archive_entry_free(entry); 990 991 out: 992 talloc_free(ctx); 993 return err; 994 } 995 996 /** 997 * tar_extract - open archive and send files. 998 */ 999 static int tar_extract(struct tar *t) 1000 { 1001 int err = 0; 1002 int r; 1003 struct archive_entry *entry; 1004 const size_t bsize = t->mode.blocksize * TAR_BLOCK_UNIT; 1005 int rc; 1006 1007 t->archive = archive_read_new(); 1008 archive_read_support_format_all(t->archive); 1009 #ifdef HAVE_ARCHIVE_READ_SUPPORT_FILTER_ALL 1010 archive_read_support_filter_all(t->archive); 1011 #endif 1012 1013 if (strequal(t->tar_path, "-")) { 1014 r = archive_read_open_fd(t->archive, STDIN_FILENO, bsize); 1015 } else { 1016 r = archive_read_open_filename(t->archive, t->tar_path, bsize); 1017 } 1018 1019 if (r != ARCHIVE_OK) { 1020 DBG(0, ("Can't open %s : %s\n", t->tar_path, 1021 archive_error_string(t->archive))); 1022 err = 1; 1023 goto out; 1024 } 1025 1026 for (;;) { 1027 NTSTATUS status; 1028 bool skip; 1029 r = archive_read_next_header(t->archive, &entry); 1030 if (r == ARCHIVE_EOF) { 1031 break; 1032 } 1033 if (r == ARCHIVE_WARN) { 1034 DBG(0, ("Warning: %s\n", archive_error_string(t->archive))); 1035 } 1036 if (r == ARCHIVE_FATAL) { 1037 DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); 1038 err = 1; 1039 goto out; 1040 } 1041 1042 status = tar_extract_skip_path(t, entry, &skip); 1043 if (!NT_STATUS_IS_OK(status)) { 1044 err = 1; 1045 goto out; 1046 } 1047 if (skip) { 1048 DBG(5, ("--- %s\n", archive_entry_pathname(entry))); 1049 continue; 1050 } 1051 1052 DBG(5, ("+++ %s\n", archive_entry_pathname(entry))); 1053 1054 rc = tar_send_file(t, entry); 1055 if (rc != 0) { 1056 err = 1; 1057 goto out; 1058 } 1059 } 1060 1061 out: 1062 #ifdef HAVE_ARCHIVE_READ_FREE 1063 r = archive_read_free(t->archive); 1064 #else 1065 r = archive_read_finish(t->archive); 1066 #endif 1067 if (r != ARCHIVE_OK) { 1068 DBG(0, ("Can't close %s : %s\n", t->tar_path, 1069 archive_error_string(t->archive))); 1070 err = 1; 1071 } 1072 return err; 1073 } 1074 1075 /** 1076 * tar_send_file - send @entry to the remote server 1077 * @entry: current archive entry 1078 * 1079 * Handle the creation of the parent directories and transfer the 1080 * entry to a new remote file. 1081 */ 1082 static int tar_send_file(struct tar *t, struct archive_entry *entry) 1083 { 1084 extern struct cli_state *cli; 1085 char *dos_path; 1086 char *full_path; 1087 NTSTATUS status; 1088 uint16_t remote_fd = (uint16_t) -1; 1089 int err = 0; 1090 int flags = O_RDWR | O_CREAT | O_TRUNC; 1091 mode_t mode = archive_entry_filetype(entry); 1092 int rc; 1093 TALLOC_CTX *ctx = talloc_new(NULL); 1094 if (ctx == NULL) { 1095 return 1; 1096 } 1097 1098 dos_path = talloc_strdup(ctx, archive_entry_pathname(entry)); 1099 if (dos_path == NULL) { 1100 err = 1; 1101 goto out; 1102 } 1103 fix_unix_path(dos_path, true); 1104 1105 full_path = talloc_strdup(ctx, client_get_cur_dir()); 1106 if (full_path == NULL) { 1107 err = 1; 1108 goto out; 1109 } 1110 full_path = talloc_strdup_append(full_path, dos_path); 1111 if (full_path == NULL) { 1112 err = 1; 1113 goto out; 1114 } 1115 1116 if (mode != AE_IFREG && mode != AE_IFDIR) { 1117 DBG(0, ("Skipping non-dir & non-regular file %s\n", full_path)); 1118 goto out; 1119 } 1120 1121 rc = make_remote_path(full_path); 1122 if (rc != 0) { 1123 err = 1; 1124 goto out; 1125 } 1126 1127 if (mode == AE_IFDIR) { 1128 goto out; 1129 } 1130 1131 status = cli_open(cli, full_path, flags, DENY_NONE, &remote_fd); 1132 if (!NT_STATUS_IS_OK(status)) { 1133 DBG(0, ("Error opening remote file %s: %s\n", 1134 full_path, nt_errstr(status))); 1135 err = 1; 1136 goto out; 1137 } 1138 1139 for (;;) { 1140 const void *buf; 1141 size_t len; 1142 off_t off; 1143 int r; 1144 1145 r = archive_read_data_block(t->archive, &buf, &len, &off); 1146 if (r == ARCHIVE_EOF) { 1147 break; 1148 } 1149 if (r == ARCHIVE_WARN) { 1150 DBG(0, ("Warning: %s\n", archive_error_string(t->archive))); 1151 } 1152 if (r == ARCHIVE_FATAL) { 1153 DBG(0, ("Fatal: %s\n", archive_error_string(t->archive))); 1154 err = 1; 1155 goto close_out; 1156 } 1157 1158 status = cli_writeall(cli, remote_fd, 0, buf, off, len, NULL); 1159 if (!NT_STATUS_IS_OK(status)) { 1160 DBG(0, ("Error writing remote file %s: %s\n", 1161 full_path, nt_errstr(status))); 1162 err = 1; 1163 goto close_out; 1164 } 1165 } 1166 1167 close_out: 1168 status = cli_close(cli, remote_fd); 1169 if (!NT_STATUS_IS_OK(status)) { 1170 DBG(0, ("Error losing remote file %s: %s\n", 1171 full_path, nt_errstr(status))); 1172 err = 1; 1173 } 1174 1175 out: 1176 talloc_free(ctx); 1177 return err; 1178 } 1179 1180 /** 1181 * tar_add_selection_path - add a path to the path list 1182 * @path: path to add 1183 */ 1184 static NTSTATUS tar_add_selection_path(struct tar *t, const char *path) 1185 { 1186 const char **list; 1187 TALLOC_CTX *ctx = t->talloc_ctx; 1188 if (!t->path_list) { 1189 t->path_list = str_list_make_empty(ctx); 1190 if (t->path_list == NULL) { 1191 return NT_STATUS_NO_MEMORY; 1192 } 1193 t->path_list_size = 0; 1194 } 1195 1196 /* cast to silence gcc const-qual warning */ 1197 list = str_list_add((void *)t->path_list, path); 1198 if (list == NULL) { 1199 return NT_STATUS_NO_MEMORY; 1200 } 1201 t->path_list = discard_const_p(char *, list); 1202 t->path_list_size++; 1203 fix_unix_path(t->path_list[t->path_list_size - 1], true); 1204 1205 return NT_STATUS_OK; 1206 } 1207 1208 /** 1209 * tar_set_blocksize - set block size in TAR_BLOCK_UNIT 1210 */ 1211 static int tar_set_blocksize(struct tar *t, int size) 1212 { 1213 if (size <= 0 || size > TAR_MAX_BLOCK_SIZE) { 1214 return 1; 1215 } 1216 1217 t->mode.blocksize = size; 1218 1219 return 0; 1220 } 1221 1222 /** 1223 * tar_set_newer_than - set date threshold of saved files 1224 * @filename: local path to a file 1225 * 1226 * Only files newer than the modification time of @filename will be 1227 * saved. 1228 * 1229 * Note: this function set the global variable newer_than from 1230 * client.c. Thus the time is not a field of the tar structure. See 1231 * cmd_newer() to change its value from an interactive session. 1232 */ 1233 static int tar_set_newer_than(struct tar *t, const char *filename) 1234 { 1235 extern time_t newer_than; 1236 SMB_STRUCT_STAT stbuf; 1237 int rc; 1238 1239 rc = sys_stat(filename, &stbuf, false); 1240 if (rc != 0) { 1241 DBG(0, ("Error setting newer-than time\n")); 1242 return 1; 1243 } 1244 1245 newer_than = convert_timespec_to_time_t(stbuf.st_ex_mtime); 1246 DBG(1, ("Getting files newer than %s\n", time_to_asc(newer_than))); 1247 return 0; 1248 } 1249 1250 /** 1251 * tar_read_inclusion_file - set path list from file 1252 * @filename: path to the list file 1253 * 1254 * Read and add each line of @filename to the path list. 1255 */ 1256 static int tar_read_inclusion_file(struct tar *t, const char* filename) 1257 { 1258 char *line; 1259 int err = 0; 1260 int fd; 1261 TALLOC_CTX *ctx = talloc_new(NULL); 1262 if (ctx == NULL) { 1263 return 1; 1264 } 1265 1266 fd = open(filename, O_RDONLY); 1267 if (fd < 0) { 1268 DBG(0, ("Can't open inclusion file '%s': %s\n", filename, strerror(errno))); 1269 err = 1; 1270 goto out; 1271 } 1272 1273 for (line = afdgets(fd, ctx, 0); 1274 line != NULL; 1275 line = afdgets(fd, ctx, 0)) { 1276 NTSTATUS status; 1277 status = tar_add_selection_path(t, line); 1278 if (!NT_STATUS_IS_OK(status)) { 1279 err = 1; 1280 goto out; 1281 } 1282 } 1283 1284 close(fd); 1285 1286 out: 1287 talloc_free(ctx); 1288 return err; 1289 } 1290 1291 /** 1292 * tar_path_in_list - check whether @path is in the path list 1293 * @path: path to find 1294 * @reverse: when true also try to find path list element in @path 1295 * @_is_in_list: set if @path is in the path list 1296 * 1297 * Look at each path of the path list and set @_is_in_list if @path is a 1298 * subpath of one of them. 1299 * 1300 * If you want /path to be in the path list (path/a/, path/b/) set 1301 * @reverse to true to try to match the other way around. 1302 */ 1303 static NTSTATUS tar_path_in_list(struct tar *t, const char *path, 1304 bool reverse, bool *_is_in_list) 1305 { 1306 int i; 1307 const char *p; 1308 const char *pattern; 1309 1310 if (path == NULL || path[0] == '\0') { 1311 *_is_in_list = false; 1312 return NT_STATUS_OK; 1313 } 1314 1315 p = skip_useless_char_in_path(path); 1316 1317 for (i = 0; i < t->path_list_size; i++) { 1318 bool is_in_list; 1319 NTSTATUS status; 1320 1321 pattern = skip_useless_char_in_path(t->path_list[i]); 1322 status = is_subpath(p, pattern, &is_in_list); 1323 if (!NT_STATUS_IS_OK(status)) { 1324 return status; 1325 } 1326 if (reverse && !is_in_list) { 1327 status = is_subpath(pattern, p, &is_in_list); 1328 if (!NT_STATUS_IS_OK(status)) { 1329 return status; 1330 } 1331 } 1332 if (is_in_list) { 1333 *_is_in_list = true; 1334 return NT_STATUS_OK; 1335 } 1336 } 1337 1338 *_is_in_list = false; 1339 return NT_STATUS_OK; 1340 } 1341 1342 /** 1343 * tar_extract_skip_path - check if @entry should be skipped 1344 * @entry: current tar entry 1345 * @_skip: set true if path should be skipped, otherwise false 1346 * 1347 * Skip predicate for tar extraction (archive to server) only. 1348 */ 1349 static NTSTATUS tar_extract_skip_path(struct tar *t, 1350 struct archive_entry *entry, 1351 bool *_skip) 1352 { 1353 const char *fullpath = archive_entry_pathname(entry); 1354 bool in = true; 1355 1356 if (t->path_list_size <= 0) { 1357 *_skip = false; 1358 return NT_STATUS_OK; 1359 } 1360 1361 if (t->mode.regex) { 1362 in = mask_match_list(fullpath, t->path_list, t->path_list_size, true); 1363 } else { 1364 NTSTATUS status = tar_path_in_list(t, fullpath, false, &in); 1365 if (!NT_STATUS_IS_OK(status)) { 1366 return status; 1367 } 1368 } 1369 1370 if (t->mode.selection == TAR_EXCLUDE) { 1371 *_skip = in; 1372 } else { 1373 *_skip = !in; 1374 } 1375 1376 return NT_STATUS_OK; 1377 } 1378 1379 /** 1380 * tar_create_skip_path - check if @fullpath shoud be skipped 1381 * @fullpath: full remote path of the current file 1382 * @finfo: remote file attributes 1383 * @_skip: returned skip not 1384 * 1385 * Skip predicate for tar creation (server to archive) only. 1386 */ 1387 static NTSTATUS tar_create_skip_path(struct tar *t, 1388 const char *fullpath, 1389 const struct file_info *finfo, 1390 bool *_skip) 1391 { 1392 /* syntaxic sugar */ 1393 const mode_t mode = finfo->mode; 1394 const bool isdir = mode & FILE_ATTRIBUTE_DIRECTORY; 1395 const bool exclude = t->mode.selection == TAR_EXCLUDE; 1396 bool in = true; 1397 1398 if (!isdir) { 1399 1400 /* 1. if we don't want X and we have X, skip */ 1401 if (!t->mode.system && (mode & FILE_ATTRIBUTE_SYSTEM)) { 1402 *_skip = true; 1403 return NT_STATUS_OK; 1404 } 1405 1406 if (!t->mode.hidden && (mode & FILE_ATTRIBUTE_HIDDEN)) { 1407 *_skip = true; 1408 return NT_STATUS_OK; 1409 } 1410 1411 /* 2. if we only want archive and it's not, skip */ 1412 1413 if (t->mode.incremental && !(mode & FILE_ATTRIBUTE_ARCHIVE)) { 1414 *_skip = true; 1415 return NT_STATUS_OK; 1416 } 1417 } 1418 1419 /* 3. is it in the selection list? */ 1420 1421 /* 1422 * tar_create_from_list() use the include list as a starting 1423 * point, no need to check 1424 */ 1425 if (!exclude) { 1426 *_skip = false; 1427 return NT_STATUS_OK; 1428 } 1429 1430 /* we are now in exclude mode */ 1431 1432 /* no matter the selection, no list => include everything */ 1433 if (t->path_list_size <= 0) { 1434 *_skip = false; 1435 return NT_STATUS_OK; 1436 } 1437 1438 if (t->mode.regex) { 1439 in = mask_match_list(fullpath, t->path_list, t->path_list_size, true); 1440 } else { 1441 bool reverse = isdir && !exclude; 1442 NTSTATUS status = tar_path_in_list(t, fullpath, reverse, &in); 1443 if (!NT_STATUS_IS_OK(status)) { 1444 return status; 1445 } 1446 } 1447 *_skip = in; 1448 1449 return NT_STATUS_OK; 1450 } 1451 1452 /** 1453 * tar_to_process - return true if @t is ready to be processed 1454 * 1455 * @t is ready if it properly parsed command line arguments. 1456 */ 1457 bool tar_to_process(struct tar *t) 1458 { 1459 if (t == NULL) { 1460 DBG(0, ("Invalid tar context\n")); 1461 return false; 1462 } 1463 return t->to_process; 1464 } 1465 1466 /** 1467 * skip_useless_char_in_path - skip leading slashes/dots 1468 * 1469 * Skip leading slashes, backslashes and dot-slashes. 1470 */ 1471 static const char* skip_useless_char_in_path(const char *p) 1472 { 1473 while (p) { 1474 if (*p == '/' || *p == '\\') { 1475 p++; 1476 } 1477 else if (p[0] == '.' && (p[1] == '/' || p[1] == '\\')) { 1478 p += 2; 1479 } 1480 else 1481 return p; 1482 } 1483 return p; 1484 } 1485 1486 /** 1487 * is_subpath - check if the path @sub is a subpath of @full. 1488 * @sub: path to test 1489 * @full: container path 1490 * @_subpath_match: set true if @sub is a subpath of @full, otherwise false 1491 * 1492 * String comparaison is case-insensitive. 1493 */ 1494 static NTSTATUS is_subpath(const char *sub, const char *full, 1495 bool *_subpath_match) 1496 { 838 1497 NTSTATUS status = NT_STATUS_OK; 839 840 if (strequal(finfo->name,"..") || strequal(finfo->name,".")) { 841 status = NT_STATUS_OK; 842 goto cleanup; 843 } 844 845 /* Is it on the exclude list ? */ 846 if (!tar_excl && clipn) { 847 char *exclaim; 848 849 DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(client_get_cur_dir()))); 850 851 exclaim = talloc_asprintf(ctx, 852 "%s\\%s", 853 client_get_cur_dir(), 854 finfo->name); 855 if (!exclaim) { 856 status = NT_STATUS_NO_MEMORY; 857 goto cleanup; 858 } 859 860 DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); 861 862 if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) || 863 (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) { 864 DEBUG(3,("Skipping file %s\n", exclaim)); 865 TALLOC_FREE(exclaim); 866 status = NT_STATUS_OK; 867 goto cleanup; 868 } 869 TALLOC_FREE(exclaim); 870 } 871 872 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { 873 char *saved_curdir = NULL; 874 char *new_cd = NULL; 875 char *mtar_mask = NULL; 876 877 saved_curdir = talloc_strdup(ctx, client_get_cur_dir()); 878 if (!saved_curdir) { 879 status = NT_STATUS_NO_MEMORY; 880 goto cleanup; 881 } 882 883 DEBUG(5, ("strlen(cur_dir)=%d, \ 884 strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", 885 (int)strlen(saved_curdir), 886 (int)strlen(finfo->name), finfo->name, saved_curdir)); 887 888 new_cd = talloc_asprintf(ctx, 889 "%s%s\\", 890 client_get_cur_dir(), 891 finfo->name); 892 if (!new_cd) { 893 status = NT_STATUS_NO_MEMORY; 894 goto cleanup; 895 } 896 client_set_cur_dir(new_cd); 897 898 DEBUG(5, ("Writing a dir, Name = %s\n", client_get_cur_dir())); 899 900 /* write a tar directory, don't bother with mode - just 901 * set it to 40755 */ 902 writetarheader(tarhandle, client_get_cur_dir(), 0, 903 finfo->mtime_ts.tv_sec, "040755 \0", '5'); 904 if (tar_noisy) { 905 DEBUG(0,(" directory %s\n", 906 client_get_cur_dir())); 907 } 908 ntarf++; /* Make sure we have a file on there */ 909 mtar_mask = talloc_asprintf(ctx, 910 "%s*", 911 client_get_cur_dir()); 912 if (!mtar_mask) { 913 status = NT_STATUS_NO_MEMORY; 914 goto cleanup; 915 } 916 DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask)); 917 do_list(mtar_mask, attribute, do_tar, False, True); 918 client_set_cur_dir(saved_curdir); 919 TALLOC_FREE(saved_curdir); 920 TALLOC_FREE(new_cd); 921 TALLOC_FREE(mtar_mask); 922 } else { 923 char *rname = talloc_asprintf(ctx, 924 "%s%s", 925 client_get_cur_dir(), 926 finfo->name); 927 if (!rname) { 928 status = NT_STATUS_NO_MEMORY; 929 goto cleanup; 930 } 931 status = do_atar(rname,finfo->name,finfo); 932 TALLOC_FREE(rname); 933 } 934 935 cleanup: 936 TALLOC_FREE(ctx); 1498 int len = 0; 1499 char *f, *s; 1500 TALLOC_CTX *tmp_ctx = talloc_new(NULL); 1501 if (tmp_ctx == NULL) { 1502 status = NT_STATUS_NO_MEMORY; 1503 goto out; 1504 } 1505 1506 f = strlower_talloc(tmp_ctx, full); 1507 if (f == NULL) { 1508 status = NT_STATUS_NO_MEMORY; 1509 goto out_ctx_free; 1510 } 1511 string_replace(f, '\\', '/'); 1512 s = strlower_talloc(tmp_ctx, sub); 1513 if (f == NULL) { 1514 status = NT_STATUS_NO_MEMORY; 1515 goto out_ctx_free; 1516 } 1517 string_replace(s, '\\', '/'); 1518 1519 /* find the point where sub and full diverge */ 1520 while ((*f != '\0') && (*s != '\0') && (*f == *s)) { 1521 f++; 1522 s++; 1523 len++; 1524 } 1525 1526 if ((*f == '\0') && (*s == '\0')) { 1527 *_subpath_match = true; /* sub and full match */ 1528 goto out_ctx_free; 1529 } 1530 1531 if ((*f == '\0') && (len > 0) && (*(f - 1) == '/')) { 1532 /* sub diverges from full at path separator */ 1533 *_subpath_match = true; 1534 goto out_ctx_free; 1535 } 1536 1537 if ((*s == '\0') && (strcmp(f, "/") == 0)) { 1538 /* full diverges from sub with trailing slash only */ 1539 *_subpath_match = true; 1540 goto out_ctx_free; 1541 } 1542 1543 if ((*s == '/') && (*f == '\0')) { 1544 /* sub diverges from full with extra path component */ 1545 *_subpath_match = true; 1546 goto out_ctx_free; 1547 } 1548 *_subpath_match = false; 1549 1550 out_ctx_free: 1551 talloc_free(tmp_ctx); 1552 out: 937 1553 return status; 938 1554 } 939 1555 940 /**************************************************************************** 941 Convert from UNIX to DOS file names 942 ***************************************************************************/ 943 944 static void unfixtarname(char *tptr, char *fp, int l, bool first) 945 { 946 /* remove '.' from start of file name, convert from unix /'s to 947 * dos \'s in path. Kill any absolute path names. But only if first! 1556 1557 /** 1558 * make_remote_path - recursively make remote dirs 1559 * @full_path: full hierarchy to create 1560 * 1561 * Create @full_path and each parent directories as needed. 1562 */ 1563 static int make_remote_path(const char *full_path) 1564 { 1565 extern struct cli_state *cli; 1566 char *path; 1567 char *subpath; 1568 char *state; 1569 char *last_backslash; 1570 char *p; 1571 int len; 1572 NTSTATUS status; 1573 int err = 0; 1574 TALLOC_CTX *ctx = talloc_new(NULL); 1575 if (ctx == NULL) { 1576 return 1; 1577 } 1578 1579 subpath = talloc_strdup(ctx, full_path); 1580 if (subpath == NULL) { 1581 err = 1; 1582 goto out; 1583 } 1584 path = talloc_strdup(ctx, full_path); 1585 if (path == NULL) { 1586 err = 1; 1587 goto out; 1588 } 1589 len = talloc_get_size(path) - 1; 1590 1591 last_backslash = strrchr_m(path, '\\'); 1592 if (last_backslash == NULL) { 1593 goto out; 1594 } 1595 1596 *last_backslash = 0; 1597 1598 subpath[0] = 0; 1599 p = strtok_r(path, "\\", &state); 1600 1601 while (p != NULL) { 1602 strlcat(subpath, p, len); 1603 status = cli_chkpath(cli, subpath); 1604 if (!NT_STATUS_IS_OK(status)) { 1605 status = cli_mkdir(cli, subpath); 1606 if (!NT_STATUS_IS_OK(status)) { 1607 DBG(0, ("Can't mkdir %s: %s\n", subpath, nt_errstr(status))); 1608 err = 1; 1609 goto out; 1610 } 1611 DBG(3, ("mkdir %s\n", subpath)); 1612 } 1613 1614 strlcat(subpath, "\\", len); 1615 p = strtok_r(NULL, "/\\", &state); 1616 1617 } 1618 1619 out: 1620 talloc_free(ctx); 1621 return err; 1622 } 1623 1624 /** 1625 * tar_reset_mem_context - reset talloc context associated with @t 1626 * 1627 * At the start of the program the context is NULL so a new one is 1628 * allocated. On the following runs (interactive session only), simply 1629 * free the children. 1630 */ 1631 static TALLOC_CTX *tar_reset_mem_context(struct tar *t) 1632 { 1633 tar_free_mem_context(t); 1634 t->talloc_ctx = talloc_new(NULL); 1635 return t->talloc_ctx; 1636 } 1637 1638 /** 1639 * tar_free_mem_context - free talloc context associated with @t 1640 */ 1641 static void tar_free_mem_context(struct tar *t) 1642 { 1643 if (t->talloc_ctx) { 1644 talloc_free(t->talloc_ctx); 1645 t->talloc_ctx = NULL; 1646 t->path_list_size = 0; 1647 t->path_list = NULL; 1648 t->tar_path = NULL; 1649 } 1650 } 1651 1652 #define XSET(v) [v] = #v 1653 #define XTABLE(v, t) DBG(2, ("DUMP:%-20.20s = %s\n", #v, t[v])) 1654 #define XBOOL(v) DBG(2, ("DUMP:%-20.20s = %d\n", #v, v ? 1 : 0)) 1655 #define XSTR(v) DBG(2, ("DUMP:%-20.20s = %s\n", #v, v ? v : "NULL")) 1656 #define XINT(v) DBG(2, ("DUMP:%-20.20s = %d\n", #v, v)) 1657 #define XUINT64(v) DBG(2, ("DUMP:%-20.20s = %" PRIu64 "\n", #v, v)) 1658 1659 /** 1660 * tar_dump - dump tar structure on stdout 1661 */ 1662 static void tar_dump(struct tar *t) 1663 { 1664 int i; 1665 const char* op[] = { 1666 XSET(TAR_NO_OPERATION), 1667 XSET(TAR_CREATE), 1668 XSET(TAR_EXTRACT), 1669 }; 1670 1671 const char* sel[] = { 1672 XSET(TAR_NO_SELECTION), 1673 XSET(TAR_INCLUDE), 1674 XSET(TAR_EXCLUDE), 1675 }; 1676 1677 XBOOL(t->to_process); 1678 XTABLE(t->mode.operation, op); 1679 XTABLE(t->mode.selection, sel); 1680 XINT(t->mode.blocksize); 1681 XBOOL(t->mode.hidden); 1682 XBOOL(t->mode.system); 1683 XBOOL(t->mode.incremental); 1684 XBOOL(t->mode.reset); 1685 XBOOL(t->mode.dry); 1686 XBOOL(t->mode.verbose); 1687 XUINT64(t->total_size); 1688 XSTR(t->tar_path); 1689 XINT(t->path_list_size); 1690 1691 for (i = 0; t->path_list && t->path_list[i]; i++) { 1692 DBG(2, ("DUMP: t->path_list[%2d] = %s\n", i, t->path_list[i])); 1693 } 1694 1695 DBG(2, ("DUMP:t->path_list @ %p (%d elem)\n", t->path_list, i)); 1696 } 1697 #undef XSET 1698 #undef XTABLE 1699 #undef XBOOL 1700 #undef XSTR 1701 #undef XINT 1702 1703 /** 1704 * max_token - return upper limit for the number of token in @str 1705 * 1706 * The result is not exact, the actual number of token might be less 1707 * than what is returned. 1708 */ 1709 static int max_token(const char *str) 1710 { 1711 const char *s; 1712 int nb = 0; 1713 1714 if (str == NULL) { 1715 return 0; 1716 } 1717 1718 s = str; 1719 while (s[0] != '\0') { 1720 if (isspace((int)s[0])) { 1721 nb++; 1722 } 1723 s++; 1724 } 1725 1726 nb++; 1727 1728 return nb; 1729 } 1730 1731 /** 1732 * fix_unix_path - convert @path to a DOS path 1733 * @path: path to convert 1734 * @removeprefix: if true, remove leading ./ or /. 1735 */ 1736 static char *fix_unix_path(char *path, bool do_remove_prefix) 1737 { 1738 char *from = path, *to = path; 1739 1740 if (path == NULL || path[0] == '\0') { 1741 return path; 1742 } 1743 1744 /* remove prefix: 1745 * ./path => path 1746 * /path => path 948 1747 */ 949 950 DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr, (long)fp, l)); 951 952 if (first) { 953 if (*fp == '.') { 954 fp++; 955 l--; 956 } 957 if (*fp == '\\' || *fp == '/') { 958 fp++; 959 l--; 960 } 961 } 962 963 safe_strcpy(tptr, fp, l); 964 string_replace(tptr, '/', '\\'); 965 } 966 967 /**************************************************************************** 968 Move to the next block in the buffer, which may mean read in another set of 969 blocks. FIXME, we should allow more than one block to be skipped. 970 ****************************************************************************/ 971 972 static int next_block(char *ltarbuf, char **bufferp, int bufsiz) 973 { 974 int bufread, total = 0; 975 976 DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp)); 977 *bufferp += TBLOCK; 978 total = TBLOCK; 979 980 if (*bufferp >= (ltarbuf + bufsiz)) { 981 982 DEBUG(5, ("Reading more data into ltarbuf ...\n")); 983 984 /* 985 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net> 986 * Fixes bug where read can return short if coming from 987 * a pipe. 988 */ 989 990 bufread = read(tarhandle, ltarbuf, bufsiz); 991 total = bufread; 992 993 while (total < bufsiz) { 994 if (bufread < 0) { /* An error, return false */ 995 return (total > 0 ? -2 : bufread); 996 } 997 if (bufread == 0) { 998 if (total <= 0) { 999 return -2; 1000 } 1001 break; 1002 } 1003 bufread = read(tarhandle, <arbuf[total], bufsiz - total); 1004 total += bufread; 1005 } 1006 1007 DEBUG(5, ("Total bytes read ... %i\n", total)); 1008 1009 *bufferp = ltarbuf; 1010 } 1011 1012 return(total); 1013 } 1014 1015 /* Skip a file, even if it includes a long file name? */ 1016 static int skip_file(int skipsize) 1017 { 1018 int dsize = skipsize; 1019 1020 DEBUG(5, ("Skiping file. Size = %i\n", skipsize)); 1021 1022 /* FIXME, we should skip more than one block at a time */ 1023 1024 while (dsize > 0) { 1025 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { 1026 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); 1027 return(False); 1028 } 1029 dsize -= TBLOCK; 1030 } 1031 1032 return(True); 1033 } 1034 1035 /************************************************************* 1036 Get a file from the tar file and store it. 1037 When this is called, tarbuf already contains the first 1038 file block. This is a bit broken & needs fixing. 1039 **************************************************************/ 1040 1041 static int get_file(file_info2 finfo) 1042 { 1043 uint16_t fnum = (uint16_t) -1; 1044 int dsize = 0, bpos = 0; 1045 uint64_t rsize = 0, pos = 0; 1046 NTSTATUS status; 1047 1048 DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size)); 1049 1050 if (!ensurepath(finfo.name)) { 1051 DEBUG(0, ("abandoning restore\n")); 1052 return False; 1053 } 1054 1055 status = cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnum); 1056 if (!NT_STATUS_IS_OK(status)) { 1057 DEBUG(0, ("abandoning restore\n")); 1058 return False; 1059 } 1060 1061 /* read the blocks from the tar file and write to the remote file */ 1062 1063 rsize = finfo.size; /* This is how much to write */ 1064 1065 while (rsize > 0) { 1066 1067 /* We can only write up to the end of the buffer */ 1068 dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */ 1069 dsize = MIN(dsize, rsize); /* Should be only what is left */ 1070 DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos)); 1071 1072 status = cli_writeall(cli, fnum, 0, 1073 (uint8_t *)(buffer_p + bpos), pos, 1074 dsize, NULL); 1075 if (!NT_STATUS_IS_OK(status)) { 1076 DEBUG(0, ("Error writing remote file: %s\n", 1077 nt_errstr(status))); 1078 return 0; 1079 } 1080 1081 rsize -= dsize; 1082 pos += dsize; 1083 1084 /* Now figure out how much to move in the buffer */ 1085 1086 /* FIXME, we should skip more than one block at a time */ 1087 1088 /* First, skip any initial part of the part written that is left over */ 1089 /* from the end of the first TBLOCK */ 1090 1091 if ((bpos) && ((bpos + dsize) >= TBLOCK)) { 1092 dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */ 1093 bpos = 0; 1094 1095 if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */ 1096 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); 1097 return False; 1098 } 1099 } 1100 1101 /* 1102 * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>. 1103 * If the file being extracted is an exact multiple of 1104 * TBLOCK bytes then we don't want to extract the next 1105 * block from the tarfile here, as it will be done in 1106 * the caller of get_file(). 1107 */ 1108 1109 while (((rsize != 0) && (dsize >= TBLOCK)) || 1110 ((rsize == 0) && (dsize > TBLOCK))) { 1111 1112 if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { 1113 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); 1114 return False; 1115 } 1116 1117 dsize -= TBLOCK; 1118 } 1119 bpos = dsize; 1120 } 1121 1122 /* Now close the file ... */ 1123 1124 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) { 1125 DEBUG(0, ("Error %s closing remote file\n", 1126 cli_errstr(cli))); 1127 return(False); 1128 } 1129 1130 /* Now we update the creation date ... */ 1131 DEBUG(5, ("Updating creation date on %s\n", finfo.name)); 1132 1133 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime_ts.tv_sec))) { 1134 if (tar_real_noisy) { 1135 DEBUG(0, ("Could not set time on file: %s\n", finfo.name)); 1136 /*return(False); */ /* Ignore, as Win95 does not allow changes */ 1137 } 1138 } 1139 1140 ntarf++; 1141 DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size)); 1142 return(True); 1143 } 1144 1145 /* Create a directory. We just ensure that the path exists and return as there 1146 is no file associated with a directory 1147 */ 1148 static int get_dir(file_info2 finfo) 1149 { 1150 DEBUG(0, ("restore directory %s\n", finfo.name)); 1151 1152 if (!ensurepath(finfo.name)) { 1153 DEBUG(0, ("Problems creating directory\n")); 1154 return(False); 1155 } 1156 ntarf++; 1157 return(True); 1158 } 1159 1160 /* Get a file with a long file name ... first file has file name, next file 1161 has the data. We only want the long file name, as the loop in do_tarput 1162 will deal with the rest. 1163 */ 1164 static char *get_longfilename(file_info2 finfo) 1165 { 1166 /* finfo.size here is the length of the filename as written by the "/./@LongLink" name 1167 * header call. */ 1168 int namesize = finfo.size + strlen(client_get_cur_dir()) + 2; 1169 char *longname = (char *)SMB_MALLOC(namesize); 1170 int offset = 0, left = finfo.size; 1171 bool first = True; 1172 1173 DEBUG(5, ("Restoring a long file name: %s\n", finfo.name)); 1174 DEBUG(5, ("Len = %.0f\n", (double)finfo.size)); 1175 1176 if (longname == NULL) { 1177 DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize)); 1178 return(NULL); 1179 } 1180 1181 /* First, add cur_dir to the long file name */ 1182 1183 if (strlen(client_get_cur_dir()) > 0) { 1184 strncpy(longname, client_get_cur_dir(), namesize); 1185 offset = strlen(client_get_cur_dir()); 1186 } 1187 1188 /* Loop through the blocks picking up the name */ 1189 1190 while (left > 0) { 1191 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { 1192 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); 1193 SAFE_FREE(longname); 1194 return(NULL); 1195 } 1196 1197 unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--); 1198 DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p)); 1199 1200 offset += TBLOCK; 1201 left -= TBLOCK; 1202 } 1203 1204 return(longname); 1205 } 1206 1207 static void do_tarput(void) 1208 { 1209 file_info2 finfo; 1210 struct timespec tp_start; 1211 char *longfilename = NULL, linkflag; 1212 int skip = False; 1213 1214 ZERO_STRUCT(finfo); 1215 1216 clock_gettime_mono(&tp_start); 1217 DEBUG(5, ("RJS do_tarput called ...\n")); 1218 1219 buffer_p = tarbuf + tbufsiz; /* init this to force first read */ 1220 1221 /* Now read through those files ... */ 1222 while (True) { 1223 /* Get us to the next block, or the first block first time around */ 1224 if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { 1225 DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); 1226 SAFE_FREE(longfilename); 1227 return; 1228 } 1229 1230 DEBUG(5, ("Reading the next header ...\n")); 1231 1232 switch (readtarheader((union hblock *) buffer_p, 1233 &finfo, client_get_cur_dir())) { 1234 case -2: /* Hmm, not good, but not fatal */ 1235 DEBUG(0, ("Skipping %s...\n", finfo.name)); 1236 if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) { 1237 DEBUG(0, ("Short file, bailing out...\n")); 1238 SAFE_FREE(longfilename); 1239 return; 1240 } 1241 break; 1242 1243 case -1: 1244 DEBUG(0, ("abandoning restore, -1 from read tar header\n")); 1245 SAFE_FREE(longfilename); 1246 return; 1247 1248 case 0: /* chksum is zero - looks like an EOF */ 1249 DEBUG(0, ("tar: restored %d files and directories\n", ntarf)); 1250 SAFE_FREE(longfilename); 1251 return; /* Hmmm, bad here ... */ 1252 1253 default: 1254 /* No action */ 1255 break; 1256 } 1257 1258 /* Now, do we have a long file name? */ 1259 if (longfilename != NULL) { 1260 SAFE_FREE(finfo.name); /* Free the space already allocated */ 1261 finfo.name = longfilename; 1262 longfilename = NULL; 1263 } 1264 1265 /* Well, now we have a header, process the file ... */ 1266 /* Should we skip the file? We have the long name as well here */ 1267 skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) || 1268 (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True))); 1269 1270 DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name)); 1271 if (skip) { 1272 skip_file(finfo.size); 1273 continue; 1274 } 1275 1276 /* We only get this far if we should process the file */ 1277 linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag; 1278 switch (linkflag) { 1279 case '0': /* Should use symbolic names--FIXME */ 1280 /* 1281 * Skip to the next block first, so we can get the file, FIXME, should 1282 * be in get_file ... 1283 * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net> 1284 * Fixes bug where file size in tarfile is zero. 1285 */ 1286 if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) { 1287 DEBUG(0, ("Short file, bailing out...\n")); 1288 return; 1289 } 1290 if (!get_file(finfo)) { 1291 DEBUG(0, ("Abandoning restore\n")); 1292 return; 1293 } 1294 break; 1295 case '5': 1296 if (!get_dir(finfo)) { 1297 DEBUG(0, ("Abandoning restore \n")); 1298 return; 1299 } 1300 break; 1301 case 'L': 1302 SAFE_FREE(longfilename); 1303 longfilename = get_longfilename(finfo); 1304 if (!longfilename) { 1305 DEBUG(0, ("abandoning restore\n")); 1306 return; 1307 } 1308 DEBUG(5, ("Long file name: %s\n", longfilename)); 1309 break; 1310 1311 default: 1312 skip_file(finfo.size); /* Don't handle these yet */ 1313 break; 1314 } 1315 } 1316 } 1317 1318 /* 1319 * samba interactive commands 1320 */ 1321 1322 /**************************************************************************** 1323 Blocksize command 1324 ***************************************************************************/ 1748 if (do_remove_prefix) { 1749 /* /path */ 1750 if (path[0] == '/' || path[0] == '\\') { 1751 from += 1; 1752 } 1753 1754 /* ./path */ 1755 if (path[1] != '\0' && path[0] == '.' && (path[1] == '/' || path[1] == '\\')) { 1756 from += 2; 1757 } 1758 } 1759 1760 /* replace / with \ */ 1761 while (from[0] != '\0') { 1762 if (from[0] == '/') { 1763 to[0] = '\\'; 1764 } else { 1765 to[0] = from[0]; 1766 } 1767 1768 from++; 1769 to++; 1770 } 1771 to[0] = '\0'; 1772 1773 return path; 1774 } 1775 1776 /** 1777 * path_base_name - return @path basename 1778 * 1779 * If @path doesn't contain any directory separator return NULL. 1780 */ 1781 static NTSTATUS path_base_name(TALLOC_CTX *ctx, const char *path, char **_base) 1782 { 1783 char *base = NULL; 1784 int last = -1; 1785 int i; 1786 1787 for (i = 0; path[i]; i++) { 1788 if (path[i] == '\\' || path[i] == '/') { 1789 last = i; 1790 } 1791 } 1792 1793 if (last >= 0) { 1794 base = talloc_strdup(ctx, path); 1795 if (base == NULL) { 1796 return NT_STATUS_NO_MEMORY; 1797 } 1798 1799 base[last] = 0; 1800 } 1801 1802 *_base = base; 1803 return NT_STATUS_OK; 1804 } 1805 1806 #else 1807 1808 #define NOT_IMPLEMENTED DEBUG(0, ("tar mode not compiled. build with --with-libarchive\n")) 1325 1809 1326 1810 int cmd_block(void) 1327 1811 { 1328 TALLOC_CTX *ctx = talloc_tos(); 1329 char *buf; 1330 int block; 1331 1332 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 1333 DEBUG(0, ("blocksize <n>\n")); 1334 return 1; 1335 } 1336 1337 block=atoi(buf); 1338 if (block < 0 || block > 65535) { 1339 DEBUG(0, ("blocksize out of range")); 1340 return 1; 1341 } 1342 1343 blocksize=block; 1344 DEBUG(2,("blocksize is now %d\n", blocksize)); 1345 return 0; 1346 } 1347 1348 /**************************************************************************** 1349 command to set incremental / reset mode 1350 ***************************************************************************/ 1812 NOT_IMPLEMENTED; 1813 return 1; 1814 } 1351 1815 1352 1816 int cmd_tarmode(void) 1353 1817 { 1354 TALLOC_CTX *ctx = talloc_tos(); 1355 char *buf; 1356 1357 while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 1358 if (strequal(buf, "full")) 1359 tar_inc=False; 1360 else if (strequal(buf, "inc")) 1361 tar_inc=True; 1362 else if (strequal(buf, "reset")) 1363 tar_reset=True; 1364 else if (strequal(buf, "noreset")) 1365 tar_reset=False; 1366 else if (strequal(buf, "system")) 1367 tar_system=True; 1368 else if (strequal(buf, "nosystem")) 1369 tar_system=False; 1370 else if (strequal(buf, "hidden")) 1371 tar_hidden=True; 1372 else if (strequal(buf, "nohidden")) 1373 tar_hidden=False; 1374 else if (strequal(buf, "verbose") || strequal(buf, "noquiet")) 1375 tar_noisy=True; 1376 else if (strequal(buf, "quiet") || strequal(buf, "noverbose")) 1377 tar_noisy=False; 1378 else 1379 DEBUG(0, ("tarmode: unrecognised option %s\n", buf)); 1380 TALLOC_FREE(buf); 1381 } 1382 1383 DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n", 1384 tar_inc ? "incremental" : "full", 1385 tar_system ? "system" : "nosystem", 1386 tar_hidden ? "hidden" : "nohidden", 1387 tar_reset ? "reset" : "noreset", 1388 tar_noisy ? "verbose" : "quiet")); 1389 return 0; 1390 } 1391 1392 /**************************************************************************** 1393 Feeble attrib command 1394 ***************************************************************************/ 1395 1396 int cmd_setmode(void) 1397 { 1398 TALLOC_CTX *ctx = talloc_tos(); 1399 char *q; 1400 char *buf; 1401 char *fname = NULL; 1402 uint16 attra[2]; 1403 int direct=1; 1404 1405 attra[0] = attra[1] = 0; 1406 1407 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 1408 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); 1409 return 1; 1410 } 1411 1412 fname = talloc_asprintf(ctx, 1413 "%s%s", 1414 client_get_cur_dir(), 1415 buf); 1416 if (!fname) { 1417 return 1; 1418 } 1419 1420 while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 1421 q=buf; 1422 1423 while(*q) { 1424 switch (*q++) { 1425 case '+': 1426 direct=1; 1427 break; 1428 case '-': 1429 direct=0; 1430 break; 1431 case 'r': 1432 attra[direct]|=FILE_ATTRIBUTE_READONLY; 1433 break; 1434 case 'h': 1435 attra[direct]|=FILE_ATTRIBUTE_HIDDEN; 1436 break; 1437 case 's': 1438 attra[direct]|=FILE_ATTRIBUTE_SYSTEM; 1439 break; 1440 case 'a': 1441 attra[direct]|=FILE_ATTRIBUTE_ARCHIVE; 1442 break; 1443 default: 1444 DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n")); 1445 return 1; 1446 } 1447 } 1448 } 1449 1450 if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) { 1451 DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); 1452 return 1; 1453 } 1454 1455 DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET])); 1456 do_setrattr(fname, attra[ATTRSET], ATTRSET); 1457 do_setrattr(fname, attra[ATTRRESET], ATTRRESET); 1458 return 0; 1459 } 1460 1461 /** 1462 Convert list of tokens to array; dependent on above routine. 1463 Uses the global cmd_ptr from above - bit of a hack. 1464 **/ 1465 1466 static char **toktocliplist(int *ctok, const char *sep) 1467 { 1468 char *s=(char *)cmd_ptr; 1469 int ictok=0; 1470 char **ret, **iret; 1471 1472 if (!sep) 1473 sep = " \t\n\r"; 1474 1475 while(*s && strchr_m(sep,*s)) 1476 s++; 1477 1478 /* nothing left? */ 1479 if (!*s) 1480 return(NULL); 1481 1482 do { 1483 ictok++; 1484 while(*s && (!strchr_m(sep,*s))) 1485 s++; 1486 while(*s && strchr_m(sep,*s)) 1487 *s++=0; 1488 } while(*s); 1489 1490 *ctok=ictok; 1491 s=(char *)cmd_ptr; 1492 1493 if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1))) 1494 return NULL; 1495 1496 while(ictok--) { 1497 *iret++=s; 1498 if (ictok > 0) { 1499 while(*s++) 1500 ; 1501 while(!*s) 1502 s++; 1503 } 1504 } 1505 1506 ret[*ctok] = NULL; 1507 return ret; 1508 } 1509 1510 /**************************************************************************** 1511 Principal command for creating / extracting 1512 ***************************************************************************/ 1818 NOT_IMPLEMENTED; 1819 return 1; 1820 } 1513 1821 1514 1822 int cmd_tar(void) 1515 1823 { 1516 TALLOC_CTX *ctx = talloc_tos(); 1517 char *buf; 1518 char **argl = NULL; 1519 int argcl = 0; 1520 int ret; 1521 1522 if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { 1523 DEBUG(0,("tar <c|x>[IXbgan] <filename>\n")); 1524 return 1; 1525 } 1526 1527 argl=toktocliplist(&argcl, NULL); 1528 if (!tar_parseargs(argcl, argl, buf, 0)) { 1529 SAFE_FREE(argl); 1530 return 1; 1531 } 1532 1533 ret = process_tar(); 1534 SAFE_FREE(argl); 1535 return ret; 1536 } 1537 1538 /**************************************************************************** 1539 Command line (option) version 1540 ***************************************************************************/ 1541 1542 int process_tar(void) 1543 { 1544 TALLOC_CTX *ctx = talloc_tos(); 1545 int rc = 0; 1546 initarbuf(); 1547 switch(tar_type) { 1548 case 'x': 1549 1550 #if 0 1551 do_tarput2(); 1552 #else 1553 do_tarput(); 1824 NOT_IMPLEMENTED; 1825 return 1; 1826 } 1827 1828 int tar_process(struct tar* tar) 1829 { 1830 NOT_IMPLEMENTED; 1831 return 1; 1832 } 1833 1834 int tar_parse_args(struct tar *tar, const char *flag, const char **val, int valsize) 1835 { 1836 NOT_IMPLEMENTED; 1837 return 1; 1838 } 1839 1840 bool tar_to_process(struct tar *tar) 1841 { 1842 return false; 1843 } 1844 1845 struct tar *tar_get_ctx() 1846 { 1847 return NULL; 1848 } 1849 1554 1850 #endif 1555 SAFE_FREE(tarbuf);1556 close(tarhandle);1557 break;1558 case 'r':1559 case 'c':1560 if (clipn && tar_excl) {1561 int i;1562 char *tarmac = NULL;1563 1564 for (i=0; i<clipn; i++) {1565 DEBUG(5,("arg %d = %s\n", i, cliplist[i]));1566 1567 if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {1568 *(cliplist[i]+strlen(cliplist[i])-1)='\0';1569 }1570 1571 if (strrchr_m(cliplist[i], '\\')) {1572 char *p;1573 char saved_char;1574 char *saved_dir = talloc_strdup(ctx,1575 client_get_cur_dir());1576 if (!saved_dir) {1577 return 1;1578 }1579 1580 if (*cliplist[i]=='\\') {1581 tarmac = talloc_strdup(ctx,1582 cliplist[i]);1583 } else {1584 tarmac = talloc_asprintf(ctx,1585 "%s%s",1586 client_get_cur_dir(),1587 cliplist[i]);1588 }1589 if (!tarmac) {1590 return 1;1591 }1592 /*1593 * Strip off the last \\xxx1594 * xxx element of tarmac to set1595 * it as current directory.1596 */1597 p = strrchr_m(tarmac, '\\');1598 if (!p) {1599 return 1;1600 }1601 saved_char = p[1];1602 p[1] = '\0';1603 1604 client_set_cur_dir(tarmac);1605 1606 /*1607 * Restore the character we1608 * just replaced to1609 * put the pathname1610 * back as it was.1611 */1612 p[1] = saved_char;1613 1614 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));1615 do_list(tarmac,attribute,do_tar, False, True);1616 1617 client_set_cur_dir(saved_dir);1618 1619 TALLOC_FREE(saved_dir);1620 TALLOC_FREE(tarmac);1621 } else {1622 tarmac = talloc_asprintf(ctx,1623 "%s%s",1624 client_get_cur_dir(),1625 cliplist[i]);1626 if (!tarmac) {1627 return 1;1628 }1629 DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));1630 do_list(tarmac,attribute,do_tar, False, True);1631 TALLOC_FREE(tarmac);1632 }1633 }1634 } else {1635 char *mask = talloc_asprintf(ctx,1636 "%s\\*",1637 client_get_cur_dir());1638 if (!mask) {1639 return 1;1640 }1641 DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));1642 do_list(mask,attribute,do_tar,False, True);1643 TALLOC_FREE(mask);1644 }1645 1646 if (ntarf) {1647 dotareof(tarhandle);1648 }1649 close(tarhandle);1650 SAFE_FREE(tarbuf);1651 1652 DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));1653 DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));1654 break;1655 }1656 1657 if (must_free_cliplist) {1658 int i;1659 for (i = 0; i < clipn; ++i) {1660 SAFE_FREE(cliplist[i]);1661 }1662 SAFE_FREE(cliplist);1663 cliplist = NULL;1664 clipn = 0;1665 must_free_cliplist = False;1666 }1667 return rc;1668 }1669 1670 /****************************************************************************1671 Find a token (filename) in a clip list1672 ***************************************************************************/1673 1674 static int clipfind(char **aret, int ret, char *tok)1675 {1676 if (aret==NULL)1677 return 0;1678 1679 /* ignore leading slashes or dots in token */1680 while(strchr_m("/\\.", *tok))1681 tok++;1682 1683 while(ret--) {1684 char *pkey=*aret++;1685 1686 /* ignore leading slashes or dots in list */1687 while(strchr_m("/\\.", *pkey))1688 pkey++;1689 1690 if (!strslashcmp(pkey, tok))1691 return 1;1692 }1693 return 0;1694 }1695 1696 /****************************************************************************1697 Read list of files to include from the file and initialize cliplist1698 accordingly.1699 ***************************************************************************/1700 1701 static int read_inclusion_file(char *filename)1702 {1703 XFILE *inclusion = NULL;1704 char buf[PATH_MAX + 1];1705 char *inclusion_buffer = NULL;1706 int inclusion_buffer_size = 0;1707 int inclusion_buffer_sofar = 0;1708 char *p;1709 char *tmpstr;1710 int i;1711 int error = 0;1712 1713 clipn = 0;1714 buf[PATH_MAX] = '\0'; /* guarantee null-termination */1715 if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) {1716 /* XXX It would be better to include a reason for failure, but without1717 * autoconf, it's hard to use strerror, sys_errlist, etc.1718 */1719 DEBUG(0,("Unable to open inclusion file %s\n", filename));1720 return 0;1721 }1722 1723 while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {1724 if (inclusion_buffer == NULL) {1725 inclusion_buffer_size = 1024;1726 if ((inclusion_buffer = (char *)SMB_MALLOC(inclusion_buffer_size)) == NULL) {1727 DEBUG(0,("failure allocating buffer to read inclusion file\n"));1728 error = 1;1729 break;1730 }1731 }1732 1733 if (buf[strlen(buf)-1] == '\n') {1734 buf[strlen(buf)-1] = '\0';1735 }1736 1737 if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {1738 inclusion_buffer_size *= 2;1739 inclusion_buffer = (char *)SMB_REALLOC(inclusion_buffer,inclusion_buffer_size);1740 if (!inclusion_buffer) {1741 DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",1742 inclusion_buffer_size));1743 error = 1;1744 break;1745 }1746 }1747 1748 safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);1749 inclusion_buffer_sofar += strlen(buf) + 1;1750 clipn++;1751 }1752 x_fclose(inclusion);1753 1754 if (! error) {1755 /* Allocate an array of clipn + 1 char*'s for cliplist */1756 cliplist = SMB_MALLOC_ARRAY(char *, clipn + 1);1757 if (cliplist == NULL) {1758 DEBUG(0,("failure allocating memory for cliplist\n"));1759 error = 1;1760 } else {1761 cliplist[clipn] = NULL;1762 p = inclusion_buffer;1763 for (i = 0; (! error) && (i < clipn); i++) {1764 /* set current item to NULL so array will be null-terminated even if1765 * malloc fails below. */1766 cliplist[i] = NULL;1767 if ((tmpstr = (char *)SMB_MALLOC(strlen(p)+1)) == NULL) {1768 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));1769 error = 1;1770 } else {1771 unfixtarname(tmpstr, p, strlen(p) + 1, True);1772 cliplist[i] = tmpstr;1773 if ((p = strchr_m(p, '\000')) == NULL) {1774 DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));1775 abort();1776 }1777 }1778 ++p;1779 }1780 must_free_cliplist = True;1781 }1782 }1783 1784 SAFE_FREE(inclusion_buffer);1785 if (error) {1786 if (cliplist) {1787 char **pp;1788 /* We know cliplist is always null-terminated */1789 for (pp = cliplist; *pp; ++pp) {1790 SAFE_FREE(*pp);1791 }1792 SAFE_FREE(cliplist);1793 cliplist = NULL;1794 must_free_cliplist = False;1795 }1796 return 0;1797 }1798 1799 /* cliplist and its elements are freed at the end of process_tar. */1800 return 1;1801 }1802 1803 /****************************************************************************1804 Parse tar arguments. Sets tar_type, tar_excl, etc.1805 ***************************************************************************/1806 1807 int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)1808 {1809 int newOptind = Optind;1810 char tar_clipfl='\0';1811 1812 /* Reset back to defaults - could be from interactive version1813 * reset mode and archive mode left as they are though1814 */1815 tar_type='\0';1816 tar_excl=True;1817 dry_run=False;1818 1819 while (*Optarg) {1820 switch(*Optarg++) {1821 case 'c':1822 tar_type='c';1823 break;1824 case 'x':1825 if (tar_type=='c') {1826 printf("Tar must be followed by only one of c or x.\n");1827 return 0;1828 }1829 tar_type='x';1830 break;1831 case 'b':1832 if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {1833 DEBUG(0,("Option b must be followed by valid blocksize\n"));1834 return 0;1835 } else {1836 Optind++;1837 newOptind++;1838 }1839 break;1840 case 'g':1841 tar_inc=True;1842 break;1843 case 'N':1844 if (Optind>=argc) {1845 DEBUG(0,("Option N must be followed by valid file name\n"));1846 return 0;1847 } else {1848 SMB_STRUCT_STAT stbuf;1849 1850 if (sys_stat(argv[Optind], &stbuf,1851 false) == 0) {1852 newer_than = convert_timespec_to_time_t(1853 stbuf.st_ex_mtime);1854 DEBUG(1,("Getting files newer than %s",1855 time_to_asc(newer_than)));1856 newOptind++;1857 Optind++;1858 } else {1859 DEBUG(0,("Error setting newer-than time\n"));1860 return 0;1861 }1862 }1863 break;1864 case 'a':1865 tar_reset=True;1866 break;1867 case 'q':1868 tar_noisy=False;1869 break;1870 case 'I':1871 if (tar_clipfl) {1872 DEBUG(0,("Only one of I,X,F must be specified\n"));1873 return 0;1874 }1875 tar_clipfl='I';1876 break;1877 case 'X':1878 if (tar_clipfl) {1879 DEBUG(0,("Only one of I,X,F must be specified\n"));1880 return 0;1881 }1882 tar_clipfl='X';1883 break;1884 case 'F':1885 if (tar_clipfl) {1886 DEBUG(0,("Only one of I,X,F must be specified\n"));1887 return 0;1888 }1889 tar_clipfl='F';1890 break;1891 case 'r':1892 DEBUG(0, ("tar_re_search set\n"));1893 tar_re_search = True;1894 break;1895 case 'n':1896 if (tar_type == 'c') {1897 DEBUG(0, ("dry_run set\n"));1898 dry_run = True;1899 } else {1900 DEBUG(0, ("n is only meaningful when creating a tar-file\n"));1901 return 0;1902 }1903 break;1904 default:1905 DEBUG(0,("Unknown tar option\n"));1906 return 0;1907 }1908 }1909 1910 if (!tar_type) {1911 printf("Option T must be followed by one of c or x.\n");1912 return 0;1913 }1914 1915 /* tar_excl is true if cliplist lists files to be included.1916 * Both 'I' and 'F' mean include. */1917 tar_excl=tar_clipfl!='X';1918 1919 if (tar_clipfl=='F') {1920 if (argc-Optind-1 != 1) {1921 DEBUG(0,("Option F must be followed by exactly one filename.\n"));1922 return 0;1923 }1924 newOptind++;1925 /* Optind points at the tar output file, Optind+1 at the inclusion file. */1926 if (! read_inclusion_file(argv[Optind+1])) {1927 return 0;1928 }1929 } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */1930 char *tmpstr;1931 char **tmplist;1932 int clipcount;1933 1934 cliplist=argv+Optind+1;1935 clipn=argc-Optind-1;1936 clipcount = clipn;1937 1938 if ((tmplist=SMB_MALLOC_ARRAY(char *,clipn)) == NULL) {1939 DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn));1940 return 0;1941 }1942 1943 for (clipcount = 0; clipcount < clipn; clipcount++) {1944 1945 DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));1946 1947 if ((tmpstr = (char *)SMB_MALLOC(strlen(cliplist[clipcount])+1)) == NULL) {1948 DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount));1949 SAFE_FREE(tmplist);1950 return 0;1951 }1952 1953 unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True);1954 tmplist[clipcount] = tmpstr;1955 DEBUG(5, ("Processed an item, %s\n", tmpstr));1956 1957 DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));1958 }1959 1960 cliplist = tmplist;1961 must_free_cliplist = True;1962 1963 newOptind += clipn;1964 }1965 1966 if (Optind+1<argc && tar_re_search && tar_clipfl != 'F') {1967 /* Doing regular expression seaches not from an inclusion file. */1968 clipn=argc-Optind-1;1969 cliplist=argv+Optind+1;1970 newOptind += clipn;1971 }1972 1973 if (Optind>=argc || !strcmp(argv[Optind], "-")) {1974 /* Sets tar handle to either 0 or 1, as appropriate */1975 tarhandle=(tar_type=='c');1976 /*1977 * Make sure that dbf points to stderr if we are using stdout for1978 * tar output1979 */1980 if (tarhandle == 1) {1981 setup_logging("smbclient", DEBUG_STDERR);1982 }1983 if (!argv[Optind]) {1984 DEBUG(0,("Must specify tar filename\n"));1985 return 0;1986 }1987 if (!strcmp(argv[Optind], "-")) {1988 newOptind++;1989 }1990 1991 } else {1992 if (tar_type=='c' && dry_run) {1993 tarhandle=-1;1994 } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)1995 || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) {1996 DEBUG(0,("Error opening local file %s - %s\n", argv[Optind], strerror(errno)));1997 return(0);1998 }1999 newOptind++;2000 }2001 2002 return newOptind;2003 } -
vendor/current/source3/client/dnsbrowse.c
r740 r988 125 125 } 126 126 127 bresult = TALLOC_ARRAY(talloc_tos(), struct mdns_smbsrv_result, 1);127 bresult = talloc_array(talloc_tos(), struct mdns_smbsrv_result, 1); 128 128 if (bresult == NULL) { 129 129 return; … … 169 169 int revents; 170 170 171 ret = poll_one_fd(mdnsfd, POLLIN|POLLHUP, &revents, 1000);171 ret = poll_one_fd(mdnsfd, POLLIN|POLLHUP, 1000, &revents); 172 172 if (ret <= 0 && errno != EINTR) { 173 173 break; -
vendor/current/source3/client/smbspool.c
r740 r988 152 152 goto done; 153 153 } else { 154 copies = atoi(argv[4]); 154 char *p = argv[4]; 155 char *endp; 156 157 copies = strtol(p, &endp, 10); 158 if (p == endp) { 159 perror("ERROR: Unable to determine number of copies"); 160 goto done; 161 } 155 162 } 156 163 … … 246 253 setup_logging("smbspool", DEBUG_STDOUT); 247 254 248 lp_set_in_client(True); /* Make sure that we tell lp_load we are */ 249 250 load_case_tables(); 251 252 if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) { 255 smb_init_locale(); 256 257 if (!lp_load_client(get_dyn_CONFIGFILE())) { 253 258 fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", get_dyn_CONFIGFILE()); 254 259 goto done; … … 342 347 343 348 344 fprintf(stderr, "DEBUG: get_exit_code(cli=%p, nt_status=% x)\n",345 cli, NT_STATUS_V(nt_status));349 fprintf(stderr, "DEBUG: get_exit_code(cli=%p, nt_status=%s [%x])\n", 350 cli, nt_errstr(nt_status), NT_STATUS_V(nt_status)); 346 351 347 352 for (i = 0; i < ARRAY_SIZE(auth_errors); i++) { … … 405 410 *need_auth = false; 406 411 nt_status = cli_start_connection(&cli, myname, server, NULL, port, 407 Undefined, flags);412 SMB_SIGNING_DEFAULT, flags); 408 413 if (!NT_STATUS_IS_OK(nt_status)) { 409 414 fprintf(stderr, "ERROR: Connection failed: %s\n", nt_errstr(nt_status)); … … 436 441 } 437 442 438 nt_status = cli_t con_andx(cli, share, "?????", password,439 strlen(password) + 1);443 nt_status = cli_tree_connect(cli, share, "?????", password, 444 strlen(password) + 1); 440 445 if (!NT_STATUS_IS_OK(nt_status)) { 441 446 fprintf(stderr, "ERROR: Tree connect failed (%s)\n", -
vendor/current/source3/client/tree.c
r414 r988 31 31 struct tree_data { 32 32 33 guint32 type; /* Type of tree item, an SMBC_TYPE */33 guint32_t type; /* Type of tree item, an SMBC_TYPE */ 34 34 char name[256]; /* May need to change this later */ 35 35 … … 129 129 } 130 130 131 struct tree_data *make_tree_data(guint32 type, const char *name)131 struct tree_data *make_tree_data(guint32_t type, const char *name) 132 132 { 133 133 struct tree_data *p = SMB_MALLOC_P(struct tree_data);
Note:
See TracChangeset
for help on using the changeset viewer.