00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025 #include "client/client_proto.h"
00026 #include "include/rpc_client.h"
00027 #ifndef REGISTER
00028 #define REGISTER 0
00029 #endif
00030
00031 extern BOOL AllowDebugChange;
00032 extern BOOL override_logfile;
00033 extern char tar_type;
00034 extern BOOL in_client;
00035 static int port = 0;
00036 pstring cur_dir = "\\";
00037 static pstring cd_path = "";
00038 static pstring service;
00039 static pstring desthost;
00040 static pstring username;
00041 static pstring calling_name;
00042 static BOOL grepable=False;
00043 static char *cmdstr = NULL;
00044
00045 static int io_bufsize = 64512;
00046
00047 static int name_type = 0x20;
00048 extern int max_protocol;
00049
00050 static int process_tok(pstring tok);
00051 static int cmd_help(void);
00052
00053 static TALLOC_CTX *ctx;
00054 #define CREATE_ACCESS_READ READ_CONTROL_ACCESS
00055 static pstring cwd;
00056
00057
00058 #define CLIENT_TIMEOUT (30*1000)
00059 #define SHORT_TIMEOUT (5*1000)
00060
00061
00062 #define FID_UNUSED (0xFFFF)
00063
00064 time_t newer_than = 0;
00065 static int archive_level = 0;
00066
00067 static BOOL translation = False;
00068 static BOOL have_ip;
00069
00070
00071 extern int blocksize;
00072 extern BOOL tar_inc;
00073 extern BOOL tar_reset;
00074
00075
00076
00077 static BOOL prompt = True;
00078
00079 static BOOL recurse = False;
00080 static BOOL showacls = False;
00081 BOOL lowercase = False;
00082
00083 static struct in_addr dest_ip;
00084
00085 #define SEPARATORS " \t\n\r"
00086
00087 static BOOL abort_mget = True;
00088
00089 static pstring fileselection = "";
00090
00091 extern file_info def_finfo;
00092
00093
00094 SMB_BIG_UINT get_total_size = 0;
00095 unsigned int get_total_time_ms = 0;
00096 static SMB_BIG_UINT put_total_size = 0;
00097 static unsigned int put_total_time_ms = 0;
00098
00099
00100 static double dir_total;
00101
00102
00103
00104 struct cli_state *cli;
00105
00106 static char CLI_DIRSEP_CHAR = '\\';
00107 static char CLI_DIRSEP_STR[] = { '\\', '\0' };
00108
00109
00110
00111
00112
00113
00114 static int writefile(int f, char *b, int n)
00115 {
00116 int i;
00117
00118 if (!translation) {
00119 return write(f,b,n);
00120 }
00121
00122 i = 0;
00123 while (i < n) {
00124 if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n') {
00125 b++;i++;
00126 }
00127 if (write(f, b, 1) != 1) {
00128 break;
00129 }
00130 b++;
00131 i++;
00132 }
00133
00134 return(i);
00135 }
00136
00137
00138
00139
00140
00141
00142 static int readfile(char *b, int n, XFILE *f)
00143 {
00144 int i;
00145 int c;
00146
00147 if (!translation)
00148 return x_fread(b,1,n,f);
00149
00150 i = 0;
00151 while (i < (n - 1) && (i < BUFFER_SIZE)) {
00152 if ((c = x_getc(f)) == EOF) {
00153 break;
00154 }
00155
00156 if (c == '\n') {
00157 b[i++] = '\r';
00158 }
00159
00160 b[i++] = c;
00161 }
00162
00163 return(i);
00164 }
00165
00166
00167
00168
00169
00170 static void send_message(void)
00171 {
00172 int total_len = 0;
00173 int grp_id;
00174
00175 if (!cli_message_start(cli, desthost, username, &grp_id)) {
00176 d_printf("message start: %s\n", cli_errstr(cli));
00177 return;
00178 }
00179
00180
00181 d_printf("Connected. Type your message, ending it with a Control-D\n");
00182
00183 while (!feof(stdin) && total_len < 1600) {
00184 int maxlen = MIN(1600 - total_len,127);
00185 pstring msg;
00186 int l=0;
00187 int c;
00188
00189 ZERO_ARRAY(msg);
00190
00191 for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++) {
00192 if (c == '\n')
00193 msg[l++] = '\r';
00194 msg[l] = c;
00195 }
00196
00197 if ((total_len > 0) && (strlen(msg) == 0)) {
00198 break;
00199 }
00200
00201 if (!cli_message_text(cli, msg, l, grp_id)) {
00202 d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
00203 return;
00204 }
00205
00206 total_len += l;
00207 }
00208
00209 if (total_len >= 1600)
00210 d_printf("the message was truncated to 1600 bytes\n");
00211 else
00212 d_printf("sent %d bytes\n",total_len);
00213
00214 if (!cli_message_end(cli, grp_id)) {
00215 d_printf("SMBsendend failed (%s)\n",cli_errstr(cli));
00216 return;
00217 }
00218 }
00219
00220
00221
00222
00223
00224 static int do_dskattr(void)
00225 {
00226 int total, bsize, avail;
00227 struct cli_state *targetcli;
00228 pstring targetpath;
00229
00230 if ( !cli_resolve_path( "", cli, cur_dir, &targetcli, targetpath ) ) {
00231 d_printf("Error in dskattr: %s\n", cli_errstr(cli));
00232 return 1;
00233 }
00234
00235 if (!cli_dskattr(targetcli, &bsize, &total, &avail)) {
00236 d_printf("Error in dskattr: %s\n",cli_errstr(targetcli));
00237 return 1;
00238 }
00239
00240 d_printf("\n\t\t%d blocks of size %d. %d blocks available\n",
00241 total, bsize, avail);
00242
00243 return 0;
00244 }
00245
00246
00247
00248
00249
00250 static int cmd_pwd(void)
00251 {
00252 d_printf("Current directory is %s",service);
00253 d_printf("%s\n",cur_dir);
00254 return 0;
00255 }
00256
00257
00258
00259
00260
00261 static int do_cd(char *newdir)
00262 {
00263 char *p = newdir;
00264 pstring saved_dir;
00265 pstring dname;
00266 pstring targetpath;
00267 struct cli_state *targetcli;
00268 SMB_STRUCT_STAT sbuf;
00269 uint32 attributes;
00270 int ret = 1;
00271
00272 dos_format(newdir);
00273
00274
00275
00276 pstrcpy(saved_dir, cur_dir);
00277
00278 if (*p == CLI_DIRSEP_CHAR) {
00279 pstrcpy(cur_dir,p);
00280 } else {
00281 pstrcat(cur_dir,p);
00282 }
00283
00284
00285 if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != CLI_DIRSEP_CHAR)) {
00286 pstrcat(cur_dir, CLI_DIRSEP_STR);
00287 }
00288
00289 clean_name(cur_dir);
00290 pstrcpy( dname, cur_dir );
00291
00292 if ( !cli_resolve_path( "", cli, dname, &targetcli, targetpath ) ) {
00293 d_printf("cd %s: %s\n", dname, cli_errstr(cli));
00294 pstrcpy(cur_dir,saved_dir);
00295 goto out;
00296 }
00297
00298 if (strequal(targetpath,CLI_DIRSEP_STR )) {
00299 return 0;
00300 }
00301
00302
00303
00304
00305 if ( targetcli->protocol > PROTOCOL_LANMAN2 && !targetcli->win95 ) {
00306 if ( !cli_qpathinfo_basic( targetcli, targetpath, &sbuf, &attributes ) ) {
00307 d_printf("cd %s: %s\n", dname, cli_errstr(targetcli));
00308 pstrcpy(cur_dir,saved_dir);
00309 goto out;
00310 }
00311
00312 if ( !(attributes&FILE_ATTRIBUTE_DIRECTORY) ) {
00313 d_printf("cd %s: not a directory\n", dname);
00314 pstrcpy(cur_dir,saved_dir);
00315 goto out;
00316 }
00317 } else {
00318 pstrcat( targetpath, CLI_DIRSEP_STR );
00319 clean_name( targetpath );
00320
00321 if ( !cli_chkpath(targetcli, targetpath) ) {
00322 d_printf("cd %s: %s\n", dname, cli_errstr(targetcli));
00323 pstrcpy(cur_dir,saved_dir);
00324 goto out;
00325 }
00326 }
00327
00328 ret = 0;
00329
00330 out:
00331
00332 pstrcpy(cd_path,cur_dir);
00333 return ret;
00334 }
00335
00336
00337
00338
00339
00340 static int cmd_cd(void)
00341 {
00342 pstring buf;
00343 int rc = 0;
00344
00345 if (next_token_nr(NULL,buf,NULL,sizeof(buf)))
00346 rc = do_cd(buf);
00347 else
00348 d_printf("Current directory is %s\n",cur_dir);
00349
00350 return rc;
00351 }
00352
00353
00354
00355
00356
00357 static BOOL do_this_one(file_info *finfo)
00358 {
00359 if (finfo->mode & aDIR)
00360 return(True);
00361
00362 if (*fileselection &&
00363 !mask_match(finfo->name,fileselection,False)) {
00364 DEBUG(3,("mask_match %s failed\n", finfo->name));
00365 return False;
00366 }
00367
00368 if (newer_than && finfo->mtime_ts.tv_sec < newer_than) {
00369 DEBUG(3,("newer_than %s failed\n", finfo->name));
00370 return(False);
00371 }
00372
00373 if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH)) {
00374 DEBUG(3,("archive %s failed\n", finfo->name));
00375 return(False);
00376 }
00377
00378 return(True);
00379 }
00380
00381
00382
00383
00384
00385 static void display_finfo(file_info *finfo)
00386 {
00387 if (do_this_one(finfo)) {
00388 time_t t = finfo->mtime_ts.tv_sec;
00389 if (!showacls) {
00390 d_printf(" %-30s%7.7s %8.0f %s",
00391 finfo->name,
00392 attrib_string(finfo->mode),
00393 (double)finfo->size,
00394 time_to_asc(t));
00395 dir_total += finfo->size;
00396 } else {
00397 pstring afname;
00398 int fnum;
00399
00400
00401 if ( strequal(finfo->name,"..") || strequal(finfo->name,".") )
00402 return;
00403
00404 pstrcpy( afname, cwd);
00405 pstrcat( afname, CLI_DIRSEP_STR);
00406 pstrcat( afname, finfo->name);
00407
00408 d_printf( "FILENAME:%s\n", afname);
00409 d_printf( "MODE:%s\n", attrib_string(finfo->mode));
00410 d_printf( "SIZE:%.0f\n", (double)finfo->size);
00411 d_printf( "MTIME:%s", time_to_asc(t));
00412 fnum = cli_nt_create(finfo->cli, afname, CREATE_ACCESS_READ);
00413 if (fnum == -1) {
00414 DEBUG( 0, ("display_finfo() Failed to open %s: %s\n",
00415 afname,
00416 cli_errstr( finfo->cli)));
00417 } else {
00418 SEC_DESC *sd = NULL;
00419 sd = cli_query_secdesc(finfo->cli, fnum, ctx);
00420 if (!sd) {
00421 DEBUG( 0, ("display_finfo() failed to "
00422 "get security descriptor: %s",
00423 cli_errstr( finfo->cli)));
00424 } else {
00425 display_sec_desc(sd);
00426 }
00427 }
00428 }
00429 }
00430 }
00431
00432
00433
00434
00435
00436 static void do_du(file_info *finfo)
00437 {
00438 if (do_this_one(finfo)) {
00439 dir_total += finfo->size;
00440 }
00441 }
00442
00443 static BOOL do_list_recurse;
00444 static BOOL do_list_dirs;
00445 static char *do_list_queue = 0;
00446 static long do_list_queue_size = 0;
00447 static long do_list_queue_start = 0;
00448 static long do_list_queue_end = 0;
00449 static void (*do_list_fn)(file_info *);
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 static void reset_do_list_queue(void)
00468 {
00469 SAFE_FREE(do_list_queue);
00470 do_list_queue_size = 0;
00471 do_list_queue_start = 0;
00472 do_list_queue_end = 0;
00473 }
00474
00475 static void init_do_list_queue(void)
00476 {
00477 reset_do_list_queue();
00478 do_list_queue_size = 1024;
00479 do_list_queue = (char *)SMB_MALLOC(do_list_queue_size);
00480 if (do_list_queue == 0) {
00481 d_printf("malloc fail for size %d\n",
00482 (int)do_list_queue_size);
00483 reset_do_list_queue();
00484 } else {
00485 memset(do_list_queue, 0, do_list_queue_size);
00486 }
00487 }
00488
00489 static void adjust_do_list_queue(void)
00490 {
00491
00492
00493
00494
00495
00496 if (do_list_queue == NULL) {
00497 DEBUG(4,("do_list_queue is empty\n"));
00498 do_list_queue_start = do_list_queue_end = 0;
00499 return;
00500 }
00501
00502 if (do_list_queue_start == do_list_queue_end) {
00503 DEBUG(4,("do_list_queue is empty\n"));
00504 do_list_queue_start = do_list_queue_end = 0;
00505 *do_list_queue = '\0';
00506 } else if (do_list_queue_start > (do_list_queue_size / 2)) {
00507 DEBUG(4,("sliding do_list_queue backward\n"));
00508 memmove(do_list_queue,
00509 do_list_queue + do_list_queue_start,
00510 do_list_queue_end - do_list_queue_start);
00511 do_list_queue_end -= do_list_queue_start;
00512 do_list_queue_start = 0;
00513 }
00514 }
00515
00516 static void add_to_do_list_queue(const char* entry)
00517 {
00518 long new_end = do_list_queue_end + ((long)strlen(entry)) + 1;
00519 while (new_end > do_list_queue_size) {
00520 do_list_queue_size *= 2;
00521 DEBUG(4,("enlarging do_list_queue to %d\n",
00522 (int)do_list_queue_size));
00523 do_list_queue = (char *)SMB_REALLOC(do_list_queue, do_list_queue_size);
00524 if (! do_list_queue) {
00525 d_printf("failure enlarging do_list_queue to %d bytes\n",
00526 (int)do_list_queue_size);
00527 reset_do_list_queue();
00528 } else {
00529 memset(do_list_queue + do_list_queue_size / 2,
00530 0, do_list_queue_size / 2);
00531 }
00532 }
00533 if (do_list_queue) {
00534 safe_strcpy_base(do_list_queue + do_list_queue_end,
00535 entry, do_list_queue, do_list_queue_size);
00536 do_list_queue_end = new_end;
00537 DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n",
00538 entry, (int)do_list_queue_start, (int)do_list_queue_end));
00539 }
00540 }
00541
00542 static char *do_list_queue_head(void)
00543 {
00544 return do_list_queue + do_list_queue_start;
00545 }
00546
00547 static void remove_do_list_queue_head(void)
00548 {
00549 if (do_list_queue_end > do_list_queue_start) {
00550 do_list_queue_start += strlen(do_list_queue_head()) + 1;
00551 adjust_do_list_queue();
00552 DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n",
00553 (int)do_list_queue_start, (int)do_list_queue_end));
00554 }
00555 }
00556
00557 static int do_list_queue_empty(void)
00558 {
00559 return (! (do_list_queue && *do_list_queue));
00560 }
00561
00562
00563
00564
00565
00566 static void do_list_helper(const char *mntpoint, file_info *f, const char *mask, void *state)
00567 {
00568 char *dir_end;
00569
00570
00571 pstrcpy( f->dir, mask );
00572 if ( (dir_end = strrchr( f->dir, CLI_DIRSEP_CHAR )) != NULL ) {
00573 *dir_end = '\0';
00574 }
00575
00576 if (f->mode & aDIR) {
00577 if (do_list_dirs && do_this_one(f)) {
00578 do_list_fn(f);
00579 }
00580 if (do_list_recurse &&
00581 !strequal(f->name,".") &&
00582 !strequal(f->name,"..")) {
00583 pstring mask2;
00584 char *p;
00585
00586 if (!f->name[0]) {
00587 d_printf("Empty dir name returned. Possible server misconfiguration.\n");
00588 return;
00589 }
00590
00591 pstrcpy(mask2, mntpoint);
00592 pstrcat(mask2, mask);
00593 p = strrchr_m(mask2,CLI_DIRSEP_CHAR);
00594 if (!p)
00595 return;
00596 p[1] = 0;
00597 pstrcat(mask2, f->name);
00598 pstrcat(mask2,CLI_DIRSEP_STR);
00599 pstrcat(mask2,"*");
00600 add_to_do_list_queue(mask2);
00601 }
00602 return;
00603 }
00604
00605 if (do_this_one(f)) {
00606 do_list_fn(f);
00607 }
00608 }
00609
00610
00611
00612
00613
00614 void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs)
00615 {
00616 static int in_do_list = 0;
00617 struct cli_state *targetcli;
00618 pstring targetpath;
00619
00620 if (in_do_list && rec) {
00621 fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n");
00622 exit(1);
00623 }
00624
00625 in_do_list = 1;
00626
00627 do_list_recurse = rec;
00628 do_list_dirs = dirs;
00629 do_list_fn = fn;
00630
00631 if (rec) {
00632 init_do_list_queue();
00633 add_to_do_list_queue(mask);
00634
00635 while (! do_list_queue_empty()) {
00636
00637
00638
00639
00640
00641
00642
00643 pstring head;
00644 pstrcpy(head, do_list_queue_head());
00645
00646
00647
00648 if ( !cli_resolve_path( "", cli, head, &targetcli, targetpath ) ) {
00649 d_printf("do_list: [%s] %s\n", head, cli_errstr(cli));
00650 remove_do_list_queue_head();
00651 continue;
00652 }
00653
00654 cli_list(targetcli, targetpath, attribute, do_list_helper, NULL);
00655 remove_do_list_queue_head();
00656 if ((! do_list_queue_empty()) && (fn == display_finfo)) {
00657 char* next_file = do_list_queue_head();
00658 char* save_ch = 0;
00659 if ((strlen(next_file) >= 2) &&
00660 (next_file[strlen(next_file) - 1] == '*') &&
00661 (next_file[strlen(next_file) - 2] == CLI_DIRSEP_CHAR)) {
00662 save_ch = next_file +
00663 strlen(next_file) - 2;
00664 *save_ch = '\0';
00665 if (showacls)
00666 pstrcpy( cwd, next_file);
00667 }
00668 if (!showacls)
00669 d_printf("\n%s\n",next_file);
00670 if (save_ch) {
00671 *save_ch = CLI_DIRSEP_CHAR;
00672 }
00673 }
00674 }
00675 } else {
00676
00677
00678 if ( cli_resolve_path( "", cli, mask, &targetcli, targetpath ) ) {
00679 if (cli_list(targetcli, targetpath, attribute, do_list_helper, NULL) == -1)
00680 d_printf("%s listing %s\n", cli_errstr(targetcli), targetpath);
00681 }
00682 else
00683 d_printf("do_list: [%s] %s\n", mask, cli_errstr(cli));
00684
00685 }
00686
00687 in_do_list = 0;
00688 reset_do_list_queue();
00689 }
00690
00691
00692
00693
00694
00695 static int cmd_dir(void)
00696 {
00697 uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
00698 pstring mask;
00699 pstring buf;
00700 char *p=buf;
00701 int rc;
00702
00703 dir_total = 0;
00704 pstrcpy(mask,cur_dir);
00705
00706 if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
00707 dos_format(p);
00708 if (*p == CLI_DIRSEP_CHAR)
00709 pstrcpy(mask,p);
00710 else
00711 pstrcat(mask,p);
00712 } else {
00713 pstrcat(mask,"*");
00714 }
00715
00716 if (showacls) {
00717
00718 pstrcpy(cwd, cur_dir);
00719 }
00720
00721 do_list(mask, attribute, display_finfo, recurse, True);
00722
00723 rc = do_dskattr();
00724
00725 DEBUG(3, ("Total bytes listed: %.0f\n", dir_total));
00726
00727 return rc;
00728 }
00729
00730
00731
00732
00733
00734 static int cmd_du(void)
00735 {
00736 uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
00737 pstring mask;
00738 pstring buf;
00739 char *p=buf;
00740 int rc;
00741
00742 dir_total = 0;
00743 pstrcpy(mask,cur_dir);
00744
00745 if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
00746 dos_format(p);
00747 if (*p == CLI_DIRSEP_CHAR)
00748 pstrcpy(mask,p);
00749 else
00750 pstrcat(mask,p);
00751 } else {
00752 pstrcat(mask,"*");
00753 }
00754
00755 do_list(mask, attribute, do_du, recurse, True);
00756
00757 rc = do_dskattr();
00758
00759 d_printf("Total number of bytes: %.0f\n", dir_total);
00760
00761 return rc;
00762 }
00763
00764
00765
00766
00767
00768 static int do_get(char *rname, char *lname, BOOL reget)
00769 {
00770 int handle = 0, fnum;
00771 BOOL newhandle = False;
00772 char *data;
00773 struct timeval tp_start;
00774 int read_size = io_bufsize;
00775 uint16 attr;
00776 SMB_OFF_T size;
00777 off_t start = 0;
00778 off_t nread = 0;
00779 int rc = 0;
00780 struct cli_state *targetcli;
00781 pstring targetname;
00782
00783
00784 if (lowercase) {
00785 strlower_m(lname);
00786 }
00787
00788 if ( !cli_resolve_path( "", cli, rname, &targetcli, targetname ) ) {
00789 d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
00790 return 1;
00791 }
00792
00793 GetTimeOfDay(&tp_start);
00794
00795 fnum = cli_open(targetcli, targetname, O_RDONLY, DENY_NONE);
00796
00797 if (fnum == -1) {
00798 d_printf("%s opening remote file %s\n",cli_errstr(cli),rname);
00799 return 1;
00800 }
00801
00802 if(!strcmp(lname,"-")) {
00803 handle = fileno(stdout);
00804 } else {
00805 if (reget) {
00806 handle = sys_open(lname, O_WRONLY|O_CREAT, 0644);
00807 if (handle >= 0) {
00808 start = sys_lseek(handle, 0, SEEK_END);
00809 if (start == -1) {
00810 d_printf("Error seeking local file\n");
00811 return 1;
00812 }
00813 }
00814 } else {
00815 handle = sys_open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
00816 }
00817 newhandle = True;
00818 }
00819 if (handle < 0) {
00820 d_printf("Error opening local file %s\n",lname);
00821 return 1;
00822 }
00823
00824
00825 if (!cli_qfileinfo(targetcli, fnum,
00826 &attr, &size, NULL, NULL, NULL, NULL, NULL) &&
00827 !cli_getattrE(targetcli, fnum,
00828 &attr, &size, NULL, NULL, NULL)) {
00829 d_printf("getattrib: %s\n",cli_errstr(targetcli));
00830 return 1;
00831 }
00832
00833 DEBUG(1,("getting file %s of size %.0f as %s ",
00834 rname, (double)size, lname));
00835
00836 if(!(data = (char *)SMB_MALLOC(read_size))) {
00837 d_printf("malloc fail for size %d\n", read_size);
00838 cli_close(targetcli, fnum);
00839 return 1;
00840 }
00841
00842 while (1) {
00843 int n = cli_read(targetcli, fnum, data, nread + start, read_size);
00844
00845 if (n <= 0)
00846 break;
00847
00848 if (writefile(handle,data, n) != n) {
00849 d_printf("Error writing local file\n");
00850 rc = 1;
00851 break;
00852 }
00853
00854 nread += n;
00855 }
00856
00857 if (nread + start < size) {
00858 DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n",
00859 rname, (long)nread));
00860
00861 rc = 1;
00862 }
00863
00864 SAFE_FREE(data);
00865
00866 if (!cli_close(targetcli, fnum)) {
00867 d_printf("Error %s closing remote file\n",cli_errstr(cli));
00868 rc = 1;
00869 }
00870
00871 if (newhandle) {
00872 close(handle);
00873 }
00874
00875 if (archive_level >= 2 && (attr & aARCH)) {
00876 cli_setatr(cli, rname, attr & ~(uint16)aARCH, 0);
00877 }
00878
00879 {
00880 struct timeval tp_end;
00881 int this_time;
00882
00883 GetTimeOfDay(&tp_end);
00884 this_time =
00885 (tp_end.tv_sec - tp_start.tv_sec)*1000 +
00886 (tp_end.tv_usec - tp_start.tv_usec)/1000;
00887 get_total_time_ms += this_time;
00888 get_total_size += nread;
00889
00890 DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n",
00891 nread / (1.024*this_time + 1.0e-4),
00892 get_total_size / (1.024*get_total_time_ms)));
00893 }
00894
00895 return rc;
00896 }
00897
00898
00899
00900
00901
00902 static int cmd_get(void)
00903 {
00904 pstring lname;
00905 pstring rname;
00906 char *p;
00907
00908 pstrcpy(rname,cur_dir);
00909
00910 p = rname + strlen(rname);
00911
00912 if (!next_token_nr(NULL,p,NULL,sizeof(rname)-strlen(rname))) {
00913 d_printf("get <filename>\n");
00914 return 1;
00915 }
00916 pstrcpy(lname,p);
00917 clean_name(rname);
00918
00919 next_token_nr(NULL,lname,NULL,sizeof(lname));
00920
00921 return do_get(rname, lname, False);
00922 }
00923
00924
00925
00926
00927
00928 static void do_mget(file_info *finfo)
00929 {
00930 pstring rname;
00931 pstring quest;
00932 pstring saved_curdir;
00933 pstring mget_mask;
00934
00935 if (strequal(finfo->name,".") || strequal(finfo->name,".."))
00936 return;
00937
00938 if (abort_mget) {
00939 d_printf("mget aborted\n");
00940 return;
00941 }
00942
00943 if (finfo->mode & aDIR)
00944 slprintf(quest,sizeof(pstring)-1,
00945 "Get directory %s? ",finfo->name);
00946 else
00947 slprintf(quest,sizeof(pstring)-1,
00948 "Get file %s? ",finfo->name);
00949
00950 if (prompt && !yesno(quest))
00951 return;
00952
00953 if (!(finfo->mode & aDIR)) {
00954 pstrcpy(rname,cur_dir);
00955 pstrcat(rname,finfo->name);
00956 do_get(rname, finfo->name, False);
00957 return;
00958 }
00959
00960
00961 pstrcpy(saved_curdir,cur_dir);
00962
00963 pstrcat(cur_dir,finfo->name);
00964 pstrcat(cur_dir,CLI_DIRSEP_STR);
00965
00966 unix_format(finfo->name);
00967 if (lowercase)
00968 strlower_m(finfo->name);
00969
00970 if (!directory_exist(finfo->name,NULL) &&
00971 mkdir(finfo->name,0777) != 0) {
00972 d_printf("failed to create directory %s\n",finfo->name);
00973 pstrcpy(cur_dir,saved_curdir);
00974 return;
00975 }
00976
00977 if (chdir(finfo->name) != 0) {
00978 d_printf("failed to chdir to directory %s\n",finfo->name);
00979 pstrcpy(cur_dir,saved_curdir);
00980 return;
00981 }
00982
00983 pstrcpy(mget_mask,cur_dir);
00984 pstrcat(mget_mask,"*");
00985
00986 do_list(mget_mask, aSYSTEM | aHIDDEN | aDIR,do_mget,False, True);
00987 chdir("..");
00988 pstrcpy(cur_dir,saved_curdir);
00989 }
00990
00991
00992
00993
00994
00995 static int cmd_more(void)
00996 {
00997 pstring rname,lname,pager_cmd;
00998 char *pager;
00999 int fd;
01000 int rc = 0;
01001
01002 pstrcpy(rname,cur_dir);
01003
01004 slprintf(lname,sizeof(lname)-1, "%s/smbmore.XXXXXX",tmpdir());
01005 fd = smb_mkstemp(lname);
01006 if (fd == -1) {
01007 d_printf("failed to create temporary file for more\n");
01008 return 1;
01009 }
01010 close(fd);
01011
01012 if (!next_token_nr(NULL,rname+strlen(rname),NULL,sizeof(rname)-strlen(rname))) {
01013 d_printf("more <filename>\n");
01014 unlink(lname);
01015 return 1;
01016 }
01017 clean_name(rname);
01018
01019 rc = do_get(rname, lname, False);
01020
01021 pager=getenv("PAGER");
01022
01023 slprintf(pager_cmd,sizeof(pager_cmd)-1,
01024 "%s %s",(pager? pager:PAGER), lname);
01025 system(pager_cmd);
01026 unlink(lname);
01027
01028 return rc;
01029 }
01030
01031
01032
01033
01034
01035 static int cmd_mget(void)
01036 {
01037 uint16 attribute = aSYSTEM | aHIDDEN;
01038 pstring mget_mask;
01039 pstring buf;
01040 char *p=buf;
01041
01042 *mget_mask = 0;
01043
01044 if (recurse)
01045 attribute |= aDIR;
01046
01047 abort_mget = False;
01048
01049 while (next_token_nr(NULL,p,NULL,sizeof(buf))) {
01050 pstrcpy(mget_mask,cur_dir);
01051
01052 if (*p == CLI_DIRSEP_CHAR)
01053 pstrcpy(mget_mask,p);
01054 else
01055 pstrcat(mget_mask,p);
01056 do_list(mget_mask, attribute,do_mget,False,True);
01057 }
01058
01059 if (!*mget_mask) {
01060 pstrcpy(mget_mask,cur_dir);
01061 pstrcat(mget_mask,"*");
01062 do_list(mget_mask, attribute,do_mget,False,True);
01063 }
01064
01065 return 0;
01066 }
01067
01068
01069
01070
01071
01072 static BOOL do_mkdir(char *name)
01073 {
01074 struct cli_state *targetcli;
01075 pstring targetname;
01076
01077 if ( !cli_resolve_path( "", cli, name, &targetcli, targetname ) ) {
01078 d_printf("mkdir %s: %s\n", name, cli_errstr(cli));
01079 return False;
01080 }
01081
01082 if (!cli_mkdir(targetcli, targetname)) {
01083 d_printf("%s making remote directory %s\n",
01084 cli_errstr(targetcli),name);
01085 return(False);
01086 }
01087
01088 return(True);
01089 }
01090
01091
01092
01093
01094
01095 static BOOL do_altname(char *name)
01096 {
01097 pstring altname;
01098 if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli, name, altname))) {
01099 d_printf("%s getting alt name for %s\n",
01100 cli_errstr(cli),name);
01101 return(False);
01102 }
01103 d_printf("%s\n", altname);
01104
01105 return(True);
01106 }
01107
01108
01109
01110
01111
01112 static int cmd_quit(void)
01113 {
01114 cli_cm_shutdown();
01115 talloc_destroy( ctx);
01116 exit(0);
01117
01118 return 0;
01119 }
01120
01121
01122
01123
01124
01125 static int cmd_mkdir(void)
01126 {
01127 pstring mask;
01128 pstring buf;
01129 char *p=buf;
01130
01131 pstrcpy(mask,cur_dir);
01132
01133 if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
01134 if (!recurse)
01135 d_printf("mkdir <dirname>\n");
01136 return 1;
01137 }
01138 pstrcat(mask,p);
01139
01140 if (recurse) {
01141 pstring ddir;
01142 pstring ddir2;
01143 struct cli_state *targetcli;
01144 pstring targetname;
01145 *ddir2 = 0;
01146
01147 if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
01148 return 1;
01149 }
01150
01151 pstrcpy(ddir,targetname);
01152 trim_char(ddir,'.','\0');
01153 p = strtok(ddir,"/\\");
01154 while (p) {
01155 pstrcat(ddir2,p);
01156 if (!cli_chkpath(targetcli, ddir2)) {
01157 do_mkdir(ddir2);
01158 }
01159 pstrcat(ddir2,CLI_DIRSEP_STR);
01160 p = strtok(NULL,"/\\");
01161 }
01162 } else {
01163 do_mkdir(mask);
01164 }
01165
01166 return 0;
01167 }
01168
01169
01170
01171
01172
01173 static int cmd_altname(void)
01174 {
01175 pstring name;
01176 pstring buf;
01177 char *p=buf;
01178
01179 pstrcpy(name,cur_dir);
01180
01181 if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
01182 d_printf("altname <file>\n");
01183 return 1;
01184 }
01185 pstrcat(name,p);
01186
01187 do_altname(name);
01188
01189 return 0;
01190 }
01191
01192
01193
01194
01195
01196 static int do_put(char *rname, char *lname, BOOL reput)
01197 {
01198 int fnum;
01199 XFILE *f;
01200 SMB_OFF_T start = 0;
01201 off_t nread = 0;
01202 char *buf = NULL;
01203 int maxwrite = io_bufsize;
01204 int rc = 0;
01205 struct timeval tp_start;
01206 struct cli_state *targetcli;
01207 pstring targetname;
01208
01209 if ( !cli_resolve_path( "", cli, rname, &targetcli, targetname ) ) {
01210 d_printf("Failed to open %s: %s\n", rname, cli_errstr(cli));
01211 return 1;
01212 }
01213
01214 GetTimeOfDay(&tp_start);
01215
01216 if (reput) {
01217 fnum = cli_open(targetcli, targetname, O_RDWR|O_CREAT, DENY_NONE);
01218 if (fnum >= 0) {
01219 if (!cli_qfileinfo(targetcli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) &&
01220 !cli_getattrE(targetcli, fnum, NULL, &start, NULL, NULL, NULL)) {
01221 d_printf("getattrib: %s\n",cli_errstr(cli));
01222 return 1;
01223 }
01224 }
01225 } else {
01226 fnum = cli_open(targetcli, targetname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
01227 }
01228
01229 if (fnum == -1) {
01230 d_printf("%s opening remote file %s\n",cli_errstr(targetcli),rname);
01231 return 1;
01232 }
01233
01234
01235
01236
01237
01238
01239 if (!strcmp(lname, "-")) {
01240 f = x_stdin;
01241
01242 } else {
01243 f = x_fopen(lname,O_RDONLY, 0);
01244 if (f && reput) {
01245 if (x_tseek(f, start, SEEK_SET) == -1) {
01246 d_printf("Error seeking local file\n");
01247 return 1;
01248 }
01249 }
01250 }
01251
01252 if (!f) {
01253 d_printf("Error opening local file %s\n",lname);
01254 return 1;
01255 }
01256
01257 DEBUG(1,("putting file %s as %s ",lname,
01258 rname));
01259
01260 buf = (char *)SMB_MALLOC(maxwrite);
01261 if (!buf) {
01262 d_printf("ERROR: Not enough memory!\n");
01263 return 1;
01264 }
01265 while (!x_feof(f)) {
01266 int n = maxwrite;
01267 int ret;
01268
01269 if ((n = readfile(buf,n,f)) < 1) {
01270 if((n == 0) && x_feof(f))
01271 break;
01272
01273 d_printf("Error reading local file: %s\n", strerror(errno));
01274 rc = 1;
01275 break;
01276 }
01277
01278 ret = cli_write(targetcli, fnum, 0, buf, nread + start, n);
01279
01280 if (n != ret) {
01281 d_printf("Error writing file: %s\n", cli_errstr(cli));
01282 rc = 1;
01283 break;
01284 }
01285
01286 nread += n;
01287 }
01288
01289 if (!cli_close(targetcli, fnum)) {
01290 d_printf("%s closing remote file %s\n",cli_errstr(cli),rname);
01291 x_fclose(f);
01292 SAFE_FREE(buf);
01293 return 1;
01294 }
01295
01296
01297 if (f != x_stdin) {
01298 x_fclose(f);
01299 }
01300
01301 SAFE_FREE(buf);
01302
01303 {
01304 struct timeval tp_end;
01305 int this_time;
01306
01307 GetTimeOfDay(&tp_end);
01308 this_time =
01309 (tp_end.tv_sec - tp_start.tv_sec)*1000 +
01310 (tp_end.tv_usec - tp_start.tv_usec)/1000;
01311 put_total_time_ms += this_time;
01312 put_total_size += nread;
01313
01314 DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n",
01315 nread / (1.024*this_time + 1.0e-4),
01316 put_total_size / (1.024*put_total_time_ms)));
01317 }
01318
01319 if (f == x_stdin) {
01320 cli_cm_shutdown();
01321 exit(0);
01322 }
01323
01324 return rc;
01325 }
01326
01327
01328
01329
01330
01331 static int cmd_put(void)
01332 {
01333 pstring lname;
01334 pstring rname;
01335 pstring buf;
01336 char *p=buf;
01337
01338 pstrcpy(rname,cur_dir);
01339
01340 if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
01341 d_printf("put <filename>\n");
01342 return 1;
01343 }
01344 pstrcpy(lname,p);
01345
01346 if (next_token_nr(NULL,p,NULL,sizeof(buf)))
01347 pstrcat(rname,p);
01348 else
01349 pstrcat(rname,lname);
01350
01351 clean_name(rname);
01352
01353 {
01354 SMB_STRUCT_STAT st;
01355
01356
01357 if (!file_exist(lname,&st) &&
01358 (strcmp(lname,"-"))) {
01359 d_printf("%s does not exist\n",lname);
01360 return 1;
01361 }
01362 }
01363
01364 return do_put(rname, lname, False);
01365 }
01366
01367
01368
01369
01370
01371 static struct file_list {
01372 struct file_list *prev, *next;
01373 char *file_path;
01374 BOOL isdir;
01375 } *file_list;
01376
01377
01378
01379
01380
01381 static void free_file_list (struct file_list *list_head)
01382 {
01383 struct file_list *list, *next;
01384
01385 for (list = list_head; list; list = next) {
01386 next = list->next;
01387 DLIST_REMOVE(list_head, list);
01388 SAFE_FREE(list->file_path);
01389 SAFE_FREE(list);
01390 }
01391 }
01392
01393
01394
01395
01396
01397
01398 static BOOL seek_list(struct file_list *list, char *name)
01399 {
01400 while (list) {
01401 trim_string(list->file_path,"./","\n");
01402 if (strncmp(list->file_path, name, strlen(name)) != 0) {
01403 return(True);
01404 }
01405 list = list->next;
01406 }
01407
01408 return(False);
01409 }
01410
01411
01412
01413
01414
01415 static int cmd_select(void)
01416 {
01417 pstrcpy(fileselection,"");
01418 next_token_nr(NULL,fileselection,NULL,sizeof(fileselection));
01419
01420 return 0;
01421 }
01422
01423
01424
01425
01426
01427
01428 static int file_find(struct file_list **list, const char *directory,
01429 const char *expression, BOOL match)
01430 {
01431 SMB_STRUCT_DIR *dir;
01432 struct file_list *entry;
01433 struct stat statbuf;
01434 int ret;
01435 char *path;
01436 BOOL isdir;
01437 const char *dname;
01438
01439 dir = sys_opendir(directory);
01440 if (!dir)
01441 return -1;
01442
01443 while ((dname = readdirname(dir))) {
01444 if (!strcmp("..", dname))
01445 continue;
01446 if (!strcmp(".", dname))
01447 continue;
01448
01449 if (asprintf(&path, "%s/%s", directory, dname) <= 0) {
01450 continue;
01451 }
01452
01453 isdir = False;
01454 if (!match || !gen_fnmatch(expression, dname)) {
01455 if (recurse) {
01456 ret = stat(path, &statbuf);
01457 if (ret == 0) {
01458 if (S_ISDIR(statbuf.st_mode)) {
01459 isdir = True;
01460 ret = file_find(list, path, expression, False);
01461 }
01462 } else {
01463 d_printf("file_find: cannot stat file %s\n", path);
01464 }
01465
01466 if (ret == -1) {
01467 SAFE_FREE(path);
01468 sys_closedir(dir);
01469 return -1;
01470 }
01471 }
01472 entry = SMB_MALLOC_P(struct file_list);
01473 if (!entry) {
01474 d_printf("Out of memory in file_find\n");
01475 sys_closedir(dir);
01476 return -1;
01477 }
01478 entry->file_path = path;
01479 entry->isdir = isdir;
01480 DLIST_ADD(*list, entry);
01481 } else {
01482 SAFE_FREE(path);
01483 }
01484 }
01485
01486 sys_closedir(dir);
01487 return 0;
01488 }
01489
01490
01491
01492
01493
01494 static int cmd_mput(void)
01495 {
01496 pstring buf;
01497 char *p=buf;
01498
01499 while (next_token_nr(NULL,p,NULL,sizeof(buf))) {
01500 int ret;
01501 struct file_list *temp_list;
01502 char *quest, *lname, *rname;
01503
01504 file_list = NULL;
01505
01506 ret = file_find(&file_list, ".", p, True);
01507 if (ret) {
01508 free_file_list(file_list);
01509 continue;
01510 }
01511
01512 quest = NULL;
01513 lname = NULL;
01514 rname = NULL;
01515
01516 for (temp_list = file_list; temp_list;
01517 temp_list = temp_list->next) {
01518
01519 SAFE_FREE(lname);
01520 if (asprintf(&lname, "%s/", temp_list->file_path) <= 0)
01521 continue;
01522 trim_string(lname, "./", "/");
01523
01524
01525 if (temp_list->isdir) {
01526
01527
01528 SAFE_FREE(quest);
01529 if (asprintf(&quest, "Put directory %s? ", lname) < 0) break;
01530 if (prompt && !yesno(quest)) {
01531
01532 lname[strlen(lname)-1] = '/';
01533 if (!seek_list(temp_list, lname))
01534 break;
01535 } else {
01536 SAFE_FREE(rname);
01537 if(asprintf(&rname, "%s%s", cur_dir, lname) < 0) break;
01538 dos_format(rname);
01539 if (!cli_chkpath(cli, rname) &&
01540 !do_mkdir(rname)) {
01541 DEBUG (0, ("Unable to make dir, skipping..."));
01542
01543 lname[strlen(lname)-1] = '/';
01544 if (!seek_list(temp_list, lname))
01545 break;
01546 }
01547 }
01548 continue;
01549 } else {
01550 SAFE_FREE(quest);
01551 if (asprintf(&quest,"Put file %s? ", lname) < 0) break;
01552 if (prompt && !yesno(quest))
01553 continue;
01554
01555
01556 SAFE_FREE(rname);
01557 if (asprintf(&rname, "%s%s", cur_dir, lname) < 0) break;
01558 }
01559
01560 dos_format(rname);
01561
01562 do_put(rname, lname, False);
01563 }
01564 free_file_list(file_list);
01565 SAFE_FREE(quest);
01566 SAFE_FREE(lname);
01567 SAFE_FREE(rname);
01568 }
01569
01570 return 0;
01571 }
01572
01573
01574
01575
01576
01577 static int do_cancel(int job)
01578 {
01579 if (cli_printjob_del(cli, job)) {
01580 d_printf("Job %d cancelled\n",job);
01581 return 0;
01582 } else {
01583 d_printf("Error cancelling job %d : %s\n",job,cli_errstr(cli));
01584 return 1;
01585 }
01586 }
01587
01588
01589
01590
01591
01592 static int cmd_cancel(void)
01593 {
01594 pstring buf;
01595 int job;
01596
01597 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01598 d_printf("cancel <jobid> ...\n");
01599 return 1;
01600 }
01601 do {
01602 job = atoi(buf);
01603 do_cancel(job);
01604 } while (next_token_nr(NULL,buf,NULL,sizeof(buf)));
01605
01606 return 0;
01607 }
01608
01609
01610
01611
01612
01613 static int cmd_print(void)
01614 {
01615 pstring lname;
01616 pstring rname;
01617 char *p;
01618
01619 if (!next_token_nr(NULL,lname,NULL, sizeof(lname))) {
01620 d_printf("print <filename>\n");
01621 return 1;
01622 }
01623
01624 pstrcpy(rname,lname);
01625 p = strrchr_m(rname,'/');
01626 if (p) {
01627 slprintf(rname, sizeof(rname)-1, "%s-%d", p+1, (int)sys_getpid());
01628 }
01629
01630 if (strequal(lname,"-")) {
01631 slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)sys_getpid());
01632 }
01633
01634 return do_put(rname, lname, False);
01635 }
01636
01637
01638
01639
01640
01641 static void queue_fn(struct print_job_info *p)
01642 {
01643 d_printf("%-6d %-9d %s\n", (int)p->id, (int)p->size, p->name);
01644 }
01645
01646
01647
01648
01649
01650 static int cmd_queue(void)
01651 {
01652 cli_print_queue(cli, queue_fn);
01653
01654 return 0;
01655 }
01656
01657
01658
01659
01660
01661 static void do_del(file_info *finfo)
01662 {
01663 pstring mask;
01664
01665 pstr_sprintf( mask, "%s%c%s", finfo->dir, CLI_DIRSEP_CHAR, finfo->name );
01666
01667 if (finfo->mode & aDIR)
01668 return;
01669
01670 if (!cli_unlink(finfo->cli, mask)) {
01671 d_printf("%s deleting remote file %s\n",cli_errstr(finfo->cli),mask);
01672 }
01673 }
01674
01675
01676
01677
01678
01679 static int cmd_del(void)
01680 {
01681 pstring mask;
01682 pstring buf;
01683 uint16 attribute = aSYSTEM | aHIDDEN;
01684
01685 if (recurse)
01686 attribute |= aDIR;
01687
01688 pstrcpy(mask,cur_dir);
01689
01690 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01691 d_printf("del <filename>\n");
01692 return 1;
01693 }
01694 pstrcat(mask,buf);
01695
01696 do_list(mask, attribute,do_del,False,False);
01697
01698 return 0;
01699 }
01700
01701
01702
01703
01704
01705 static int cmd_wdel(void)
01706 {
01707 pstring mask;
01708 pstring buf;
01709 uint16 attribute;
01710 struct cli_state *targetcli;
01711 pstring targetname;
01712
01713 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01714 d_printf("wdel 0x<attrib> <wcard>\n");
01715 return 1;
01716 }
01717
01718 attribute = (uint16)strtol(buf, (char **)NULL, 16);
01719
01720 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01721 d_printf("wdel 0x<attrib> <wcard>\n");
01722 return 1;
01723 }
01724
01725 pstrcpy(mask,cur_dir);
01726 pstrcat(mask,buf);
01727
01728 if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
01729 d_printf("cmd_wdel %s: %s\n", mask, cli_errstr(cli));
01730 return 1;
01731 }
01732
01733 if (!cli_unlink_full(targetcli, targetname, attribute)) {
01734 d_printf("%s deleting remote files %s\n",cli_errstr(targetcli),targetname);
01735 }
01736 return 0;
01737 }
01738
01739
01740
01741
01742 static int cmd_open(void)
01743 {
01744 pstring mask;
01745 pstring buf;
01746 struct cli_state *targetcli;
01747 pstring targetname;
01748 int fnum;
01749
01750 pstrcpy(mask,cur_dir);
01751
01752 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01753 d_printf("open <filename>\n");
01754 return 1;
01755 }
01756 pstrcat(mask,buf);
01757
01758 if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
01759 d_printf("open %s: %s\n", mask, cli_errstr(cli));
01760 return 1;
01761 }
01762
01763 fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA|FILE_WRITE_DATA);
01764 if (fnum == -1) {
01765 fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA);
01766 if (fnum != -1) {
01767 d_printf("open file %s: for read/write fnum %d\n", targetname, fnum);
01768 } else {
01769 d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
01770 }
01771 } else {
01772 d_printf("open file %s: for read/write fnum %d\n", targetname, fnum);
01773 }
01774
01775 return 0;
01776 }
01777
01778
01779
01780
01781 static int cmd_posix_open(void)
01782 {
01783 pstring mask;
01784 pstring buf;
01785 struct cli_state *targetcli;
01786 pstring targetname;
01787 mode_t mode;
01788 int fnum;
01789
01790 pstrcpy(mask,cur_dir);
01791
01792 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01793 d_printf("posix_open <filename> 0<mode>\n");
01794 return 1;
01795 }
01796 pstrcat(mask,buf);
01797 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01798 d_printf("posix_open <filename> 0<mode>\n");
01799 return 1;
01800 }
01801 mode = (mode_t)strtol(buf, (char **)NULL, 8);
01802
01803 if (!cli_resolve_path( "", cli, mask, &targetcli, targetname )) {
01804 d_printf("posix_open %s: %s\n", mask, cli_errstr(cli));
01805 return 1;
01806 }
01807
01808 fnum = cli_posix_open(targetcli, targetname, O_CREAT|O_RDWR, mode);
01809 if (fnum == -1) {
01810 fnum = cli_posix_open(targetcli, targetname, O_CREAT|O_RDONLY, mode);
01811 if (fnum != -1) {
01812 d_printf("posix_open file %s: for read/write fnum %d\n", targetname, fnum);
01813 } else {
01814 d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
01815 }
01816 } else {
01817 d_printf("posix_open file %s: for read/write fnum %d\n", targetname, fnum);
01818 }
01819
01820 return 0;
01821 }
01822
01823 static int cmd_posix_mkdir(void)
01824 {
01825 pstring mask;
01826 pstring buf;
01827 struct cli_state *targetcli;
01828 pstring targetname;
01829 mode_t mode;
01830 int fnum;
01831
01832 pstrcpy(mask,cur_dir);
01833
01834 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01835 d_printf("posix_mkdir <filename> 0<mode>\n");
01836 return 1;
01837 }
01838 pstrcat(mask,buf);
01839 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01840 d_printf("posix_mkdir <filename> 0<mode>\n");
01841 return 1;
01842 }
01843 mode = (mode_t)strtol(buf, (char **)NULL, 8);
01844
01845 if (!cli_resolve_path( "", cli, mask, &targetcli, targetname )) {
01846 d_printf("posix_mkdir %s: %s\n", mask, cli_errstr(cli));
01847 return 1;
01848 }
01849
01850 fnum = cli_posix_mkdir(targetcli, targetname, mode);
01851 if (fnum == -1) {
01852 d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
01853 } else {
01854 d_printf("posix_mkdir created directory %s\n", targetname);
01855 }
01856
01857 return 0;
01858 }
01859
01860 static int cmd_posix_unlink(void)
01861 {
01862 pstring mask;
01863 pstring buf;
01864 struct cli_state *targetcli;
01865 pstring targetname;
01866
01867 pstrcpy(mask,cur_dir);
01868
01869 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01870 d_printf("posix_unlink <filename>\n");
01871 return 1;
01872 }
01873 pstrcat(mask,buf);
01874
01875 if (!cli_resolve_path( "", cli, mask, &targetcli, targetname )) {
01876 d_printf("posix_unlink %s: %s\n", mask, cli_errstr(cli));
01877 return 1;
01878 }
01879
01880 if (!cli_posix_unlink(targetcli, targetname)) {
01881 d_printf("Failed to unlink file %s. %s\n", targetname, cli_errstr(cli));
01882 } else {
01883 d_printf("posix_unlink deleted file %s\n", targetname);
01884 }
01885
01886 return 0;
01887 }
01888
01889 static int cmd_posix_rmdir(void)
01890 {
01891 pstring mask;
01892 pstring buf;
01893 struct cli_state *targetcli;
01894 pstring targetname;
01895
01896 pstrcpy(mask,cur_dir);
01897
01898 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01899 d_printf("posix_rmdir <filename>\n");
01900 return 1;
01901 }
01902 pstrcat(mask,buf);
01903
01904 if (!cli_resolve_path( "", cli, mask, &targetcli, targetname)) {
01905 d_printf("posix_rmdir %s: %s\n", mask, cli_errstr(cli));
01906 return 1;
01907 }
01908
01909 if (!cli_posix_rmdir(targetcli, targetname)) {
01910 d_printf("Failed to unlink directory %s. %s\n", targetname, cli_errstr(cli));
01911 } else {
01912 d_printf("posix_rmdir deleted directory %s\n", targetname);
01913 }
01914
01915 return 0;
01916 }
01917
01918 static int cmd_close(void)
01919 {
01920 fstring buf;
01921 int fnum;
01922
01923 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
01924 d_printf("close <fnum>\n");
01925 return 1;
01926 }
01927
01928 fnum = atoi(buf);
01929
01930 if (!cli_close(cli, fnum)) {
01931 d_printf("close %d: %s\n", fnum, cli_errstr(cli));
01932 return 1;
01933 }
01934 return 0;
01935 }
01936
01937 static int cmd_posix(void)
01938 {
01939 uint16 major, minor;
01940 uint32 caplow, caphigh;
01941 pstring caps;
01942
01943 if (!SERVER_HAS_UNIX_CIFS(cli)) {
01944 d_printf("Server doesn't support UNIX CIFS extensions.\n");
01945 return 1;
01946 }
01947
01948 if (!cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) {
01949 d_printf("Can't get UNIX CIFS extensions version from server.\n");
01950 return 1;
01951 }
01952
01953 d_printf("Server supports CIFS extensions %u.%u\n", (unsigned int)major, (unsigned int)minor);
01954
01955 *caps = '\0';
01956 if (caplow & CIFS_UNIX_FCNTL_LOCKS_CAP) {
01957 pstrcat(caps, "locks ");
01958 }
01959 if (caplow & CIFS_UNIX_POSIX_ACLS_CAP) {
01960 pstrcat(caps, "acls ");
01961 }
01962 if (caplow & CIFS_UNIX_XATTTR_CAP) {
01963 pstrcat(caps, "eas ");
01964 }
01965 if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
01966 pstrcat(caps, "pathnames ");
01967 }
01968 if (caplow & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP) {
01969 pstrcat(caps, "posix_path_operations ");
01970 }
01971
01972 if (strlen(caps) > 0 && caps[strlen(caps)-1] == ' ') {
01973 caps[strlen(caps)-1] = '\0';
01974 }
01975
01976 if (!cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh)) {
01977 d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", cli_errstr(cli));
01978 return 1;
01979 }
01980
01981 d_printf("Selecting server supported CIFS capabilities %s\n", caps);
01982
01983 if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
01984 CLI_DIRSEP_CHAR = '/';
01985 *CLI_DIRSEP_STR = '/';
01986 pstrcpy(cur_dir, CLI_DIRSEP_STR);
01987 do_cd(cur_dir);
01988 }
01989
01990 return 0;
01991 }
01992
01993 static int cmd_lock(void)
01994 {
01995 fstring buf;
01996 SMB_BIG_UINT start, len;
01997 enum brl_type lock_type;
01998 int fnum;
01999
02000 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02001 d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
02002 return 1;
02003 }
02004 fnum = atoi(buf);
02005
02006 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02007 d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
02008 return 1;
02009 }
02010
02011 if (*buf == 'r' || *buf == 'R') {
02012 lock_type = READ_LOCK;
02013 } else if (*buf == 'w' || *buf == 'W') {
02014 lock_type = WRITE_LOCK;
02015 } else {
02016 d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
02017 return 1;
02018 }
02019
02020 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02021 d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
02022 return 1;
02023 }
02024
02025 start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
02026
02027 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02028 d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
02029 return 1;
02030 }
02031
02032 len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
02033
02034 if (!cli_posix_lock(cli, fnum, start, len, True, lock_type)) {
02035 d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli));
02036 }
02037
02038 return 0;
02039 }
02040
02041 static int cmd_unlock(void)
02042 {
02043 fstring buf;
02044 SMB_BIG_UINT start, len;
02045 int fnum;
02046
02047 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02048 d_printf("unlock <fnum> <hex-start> <hex-len>\n");
02049 return 1;
02050 }
02051 fnum = atoi(buf);
02052
02053 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02054 d_printf("unlock <fnum> <hex-start> <hex-len>\n");
02055 return 1;
02056 }
02057
02058 start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
02059
02060 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02061 d_printf("unlock <fnum> <hex-start> <hex-len>\n");
02062 return 1;
02063 }
02064
02065 len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
02066
02067 if (!cli_posix_unlock(cli, fnum, start, len)) {
02068 d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli));
02069 }
02070
02071 return 0;
02072 }
02073
02074
02075
02076
02077
02078
02079 static int cmd_rmdir(void)
02080 {
02081 pstring mask;
02082 pstring buf;
02083 struct cli_state *targetcli;
02084 pstring targetname;
02085
02086 pstrcpy(mask,cur_dir);
02087
02088 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02089 d_printf("rmdir <dirname>\n");
02090 return 1;
02091 }
02092 pstrcat(mask,buf);
02093
02094 if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
02095 d_printf("rmdir %s: %s\n", mask, cli_errstr(cli));
02096 return 1;
02097 }
02098
02099 if (!cli_rmdir(targetcli, targetname)) {
02100 d_printf("%s removing remote directory file %s\n",
02101 cli_errstr(targetcli),mask);
02102 }
02103
02104 return 0;
02105 }
02106
02107
02108
02109
02110
02111 static int cmd_link(void)
02112 {
02113 pstring oldname,newname;
02114 pstring buf,buf2;
02115 struct cli_state *targetcli;
02116 pstring targetname;
02117
02118 pstrcpy(oldname,cur_dir);
02119 pstrcpy(newname,cur_dir);
02120
02121 if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
02122 !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
02123 d_printf("link <oldname> <newname>\n");
02124 return 1;
02125 }
02126
02127 pstrcat(oldname,buf);
02128 pstrcat(newname,buf2);
02129
02130 if ( !cli_resolve_path( "", cli, oldname, &targetcli, targetname ) ) {
02131 d_printf("link %s: %s\n", oldname, cli_errstr(cli));
02132 return 1;
02133 }
02134
02135 if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
02136 d_printf("Server doesn't support UNIX CIFS calls.\n");
02137 return 1;
02138 }
02139
02140 if (!cli_unix_hardlink(targetcli, targetname, newname)) {
02141 d_printf("%s linking files (%s -> %s)\n", cli_errstr(targetcli), newname, oldname);
02142 return 1;
02143 }
02144
02145 return 0;
02146 }
02147
02148
02149
02150
02151
02152 static int cmd_symlink(void)
02153 {
02154 pstring oldname,newname;
02155 pstring buf,buf2;
02156 struct cli_state *targetcli;
02157 pstring targetname;
02158
02159 if (!SERVER_HAS_UNIX_CIFS(cli)) {
02160 d_printf("Server doesn't support UNIX CIFS calls.\n");
02161 return 1;
02162 }
02163
02164 pstrcpy(newname,cur_dir);
02165
02166 if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
02167 !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
02168 d_printf("symlink <oldname> <newname>\n");
02169 return 1;
02170 }
02171
02172 pstrcpy(oldname,buf);
02173 pstrcat(newname,buf2);
02174
02175 if ( !cli_resolve_path( "", cli, oldname, &targetcli, targetname ) ) {
02176 d_printf("link %s: %s\n", oldname, cli_errstr(cli));
02177 return 1;
02178 }
02179
02180 if (!cli_unix_symlink(targetcli, targetname, newname)) {
02181 d_printf("%s symlinking files (%s -> %s)\n",
02182 cli_errstr(targetcli), newname, targetname);
02183 return 1;
02184 }
02185
02186 return 0;
02187 }
02188
02189
02190
02191
02192
02193 static int cmd_chmod(void)
02194 {
02195 pstring src;
02196 mode_t mode;
02197 pstring buf, buf2;
02198 struct cli_state *targetcli;
02199 pstring targetname;
02200
02201 pstrcpy(src,cur_dir);
02202
02203 if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
02204 !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
02205 d_printf("chmod mode file\n");
02206 return 1;
02207 }
02208
02209 mode = (mode_t)strtol(buf, NULL, 8);
02210 pstrcat(src,buf2);
02211
02212 if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
02213 d_printf("chmod %s: %s\n", src, cli_errstr(cli));
02214 return 1;
02215 }
02216
02217 if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
02218 d_printf("Server doesn't support UNIX CIFS calls.\n");
02219 return 1;
02220 }
02221
02222 if (!cli_unix_chmod(targetcli, targetname, mode)) {
02223 d_printf("%s chmod file %s 0%o\n",
02224 cli_errstr(targetcli), src, (unsigned int)mode);
02225 return 1;
02226 }
02227
02228 return 0;
02229 }
02230
02231 static const char *filetype_to_str(mode_t mode)
02232 {
02233 if (S_ISREG(mode)) {
02234 return "regular file";
02235 } else if (S_ISDIR(mode)) {
02236 return "directory";
02237 } else
02238 #ifdef S_ISCHR
02239 if (S_ISCHR(mode)) {
02240 return "character device";
02241 } else
02242 #endif
02243 #ifdef S_ISBLK
02244 if (S_ISBLK(mode)) {
02245 return "block device";
02246 } else
02247 #endif
02248 #ifdef S_ISFIFO
02249 if (S_ISFIFO(mode)) {
02250 return "fifo";
02251 } else
02252 #endif
02253 #ifdef S_ISLNK
02254 if (S_ISLNK(mode)) {
02255 return "symbolic link";
02256 } else
02257 #endif
02258 #ifdef S_ISSOCK
02259 if (S_ISSOCK(mode)) {
02260 return "socket";
02261 } else
02262 #endif
02263 return "";
02264 }
02265
02266 static char rwx_to_str(mode_t m, mode_t bt, char ret)
02267 {
02268 if (m & bt) {
02269 return ret;
02270 } else {
02271 return '-';
02272 }
02273 }
02274
02275 static char *unix_mode_to_str(char *s, mode_t m)
02276 {
02277 char *p = s;
02278 const char *str = filetype_to_str(m);
02279
02280 switch(str[0]) {
02281 case 'd':
02282 *p++ = 'd';
02283 break;
02284 case 'c':
02285 *p++ = 'c';
02286 break;
02287 case 'b':
02288 *p++ = 'b';
02289 break;
02290 case 'f':
02291 *p++ = 'p';
02292 break;
02293 case 's':
02294 *p++ = str[1] == 'y' ? 'l' : 's';
02295 break;
02296 case 'r':
02297 default:
02298 *p++ = '-';
02299 break;
02300 }
02301 *p++ = rwx_to_str(m, S_IRUSR, 'r');
02302 *p++ = rwx_to_str(m, S_IWUSR, 'w');
02303 *p++ = rwx_to_str(m, S_IXUSR, 'x');
02304 *p++ = rwx_to_str(m, S_IRGRP, 'r');
02305 *p++ = rwx_to_str(m, S_IWGRP, 'w');
02306 *p++ = rwx_to_str(m, S_IXGRP, 'x');
02307 *p++ = rwx_to_str(m, S_IROTH, 'r');
02308 *p++ = rwx_to_str(m, S_IWOTH, 'w');
02309 *p++ = rwx_to_str(m, S_IXOTH, 'x');
02310 *p++ = '\0';
02311 return s;
02312 }
02313
02314
02315
02316
02317
02318 static char *perms_to_string(fstring permstr, unsigned char perms)
02319 {
02320 fstrcpy(permstr, "---");
02321 if (perms & SMB_POSIX_ACL_READ) {
02322 permstr[0] = 'r';
02323 }
02324 if (perms & SMB_POSIX_ACL_WRITE) {
02325 permstr[1] = 'w';
02326 }
02327 if (perms & SMB_POSIX_ACL_EXECUTE) {
02328 permstr[2] = 'x';
02329 }
02330 return permstr;
02331 }
02332
02333
02334
02335
02336
02337 static int cmd_getfacl(void)
02338 {
02339 pstring src, name;
02340 uint16 major, minor;
02341 uint32 caplow, caphigh;
02342 char *retbuf = NULL;
02343 size_t rb_size = 0;
02344 SMB_STRUCT_STAT sbuf;
02345 uint16 num_file_acls = 0;
02346 uint16 num_dir_acls = 0;
02347 uint16 i;
02348 struct cli_state *targetcli;
02349 pstring targetname;
02350
02351 pstrcpy(src,cur_dir);
02352
02353 if (!next_token_nr(NULL,name,NULL,sizeof(name))) {
02354 d_printf("stat file\n");
02355 return 1;
02356 }
02357
02358 pstrcat(src,name);
02359
02360 if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
02361 d_printf("stat %s: %s\n", src, cli_errstr(cli));
02362 return 1;
02363 }
02364
02365 if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
02366 d_printf("Server doesn't support UNIX CIFS calls.\n");
02367 return 1;
02368 }
02369
02370 if (!cli_unix_extensions_version(targetcli, &major, &minor, &caplow, &caphigh)) {
02371 d_printf("Can't get UNIX CIFS version from server.\n");
02372 return 1;
02373 }
02374
02375 if (!(caplow & CIFS_UNIX_POSIX_ACLS_CAP)) {
02376 d_printf("This server supports UNIX extensions but doesn't support POSIX ACLs.\n");
02377 return 1;
02378 }
02379
02380 if (!cli_unix_stat(targetcli, targetname, &sbuf)) {
02381 d_printf("%s getfacl doing a stat on file %s\n",
02382 cli_errstr(targetcli), src);
02383 return 1;
02384 }
02385
02386 if (!cli_unix_getfacl(targetcli, targetname, &rb_size, &retbuf)) {
02387 d_printf("%s getfacl file %s\n",
02388 cli_errstr(targetcli), src);
02389 return 1;
02390 }
02391
02392
02393 if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) {
02394 d_printf("getfacl file %s, unknown POSIX acl version %u.\n",
02395 src, (unsigned int)CVAL(retbuf,0) );
02396 SAFE_FREE(retbuf);
02397 return 1;
02398 }
02399
02400 num_file_acls = SVAL(retbuf,2);
02401 num_dir_acls = SVAL(retbuf,4);
02402 if (rb_size != SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)) {
02403 d_printf("getfacl file %s, incorrect POSIX acl buffer size (should be %u, was %u).\n",
02404 src,
02405 (unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)),
02406 (unsigned int)rb_size);
02407
02408 SAFE_FREE(retbuf);
02409 return 1;
02410 }
02411
02412 d_printf("# file: %s\n", src);
02413 d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
02414
02415 if (num_file_acls == 0 && num_dir_acls == 0) {
02416 d_printf("No acls found.\n");
02417 }
02418
02419 for (i = 0; i < num_file_acls; i++) {
02420 uint32 uorg;
02421 fstring permstring;
02422 unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE));
02423 unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+1);
02424
02425 switch(tagtype) {
02426 case SMB_POSIX_ACL_USER_OBJ:
02427 d_printf("user::");
02428 break;
02429 case SMB_POSIX_ACL_USER:
02430 uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
02431 d_printf("user:%u:", uorg);
02432 break;
02433 case SMB_POSIX_ACL_GROUP_OBJ:
02434 d_printf("group::");
02435 break;
02436 case SMB_POSIX_ACL_GROUP:
02437 uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
02438 d_printf("group:%u", uorg);
02439 break;
02440 case SMB_POSIX_ACL_MASK:
02441 d_printf("mask::");
02442 break;
02443 case SMB_POSIX_ACL_OTHER:
02444 d_printf("other::");
02445 break;
02446 default:
02447 d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
02448 src, (unsigned int)tagtype );
02449 SAFE_FREE(retbuf);
02450 return 1;
02451 }
02452
02453 d_printf("%s\n", perms_to_string(permstring, perms));
02454 }
02455
02456 for (i = 0; i < num_dir_acls; i++) {
02457 uint32 uorg;
02458 fstring permstring;
02459 unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE));
02460 unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+1);
02461
02462 switch(tagtype) {
02463 case SMB_POSIX_ACL_USER_OBJ:
02464 d_printf("default:user::");
02465 break;
02466 case SMB_POSIX_ACL_USER:
02467 uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
02468 d_printf("default:user:%u:", uorg);
02469 break;
02470 case SMB_POSIX_ACL_GROUP_OBJ:
02471 d_printf("default:group::");
02472 break;
02473 case SMB_POSIX_ACL_GROUP:
02474 uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
02475 d_printf("default:group:%u", uorg);
02476 break;
02477 case SMB_POSIX_ACL_MASK:
02478 d_printf("default:mask::");
02479 break;
02480 case SMB_POSIX_ACL_OTHER:
02481 d_printf("default:other::");
02482 break;
02483 default:
02484 d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
02485 src, (unsigned int)tagtype );
02486 SAFE_FREE(retbuf);
02487 return 1;
02488 }
02489
02490 d_printf("%s\n", perms_to_string(permstring, perms));
02491 }
02492
02493 SAFE_FREE(retbuf);
02494 return 0;
02495 }
02496
02497
02498
02499
02500
02501 static int cmd_stat(void)
02502 {
02503 pstring src, name;
02504 fstring mode_str;
02505 SMB_STRUCT_STAT sbuf;
02506 struct cli_state *targetcli;
02507 struct tm *lt;
02508 pstring targetname;
02509
02510 if (!SERVER_HAS_UNIX_CIFS(cli)) {
02511 d_printf("Server doesn't support UNIX CIFS calls.\n");
02512 return 1;
02513 }
02514
02515 pstrcpy(src,cur_dir);
02516
02517 if (!next_token_nr(NULL,name,NULL,sizeof(name))) {
02518 d_printf("stat file\n");
02519 return 1;
02520 }
02521
02522 pstrcat(src,name);
02523
02524
02525 if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
02526 d_printf("stat %s: %s\n", src, cli_errstr(cli));
02527 return 1;
02528 }
02529
02530 if (!cli_unix_stat(targetcli, targetname, &sbuf)) {
02531 d_printf("%s stat file %s\n",
02532 cli_errstr(targetcli), src);
02533 return 1;
02534 }
02535
02536
02537 d_printf("File: %s\n", src);
02538 d_printf("Size: %-12.0f\tBlocks: %u\t%s\n",
02539 (double)sbuf.st_size,
02540 (unsigned int)sbuf.st_blocks,
02541 filetype_to_str(sbuf.st_mode));
02542
02543 #if defined(S_ISCHR) && defined(S_ISBLK)
02544 if (S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode)) {
02545 d_printf("Inode: %.0f\tLinks: %u\tDevice type: %u,%u\n",
02546 (double)sbuf.st_ino,
02547 (unsigned int)sbuf.st_nlink,
02548 unix_dev_major(sbuf.st_rdev),
02549 unix_dev_minor(sbuf.st_rdev));
02550 } else
02551 #endif
02552 d_printf("Inode: %.0f\tLinks: %u\n",
02553 (double)sbuf.st_ino,
02554 (unsigned int)sbuf.st_nlink);
02555
02556 d_printf("Access: (0%03o/%s)\tUid: %u\tGid: %u\n",
02557 ((int)sbuf.st_mode & 0777),
02558 unix_mode_to_str(mode_str, sbuf.st_mode),
02559 (unsigned int)sbuf.st_uid,
02560 (unsigned int)sbuf.st_gid);
02561
02562 lt = localtime(&sbuf.st_atime);
02563 if (lt) {
02564 strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
02565 } else {
02566 fstrcpy(mode_str, "unknown");
02567 }
02568 d_printf("Access: %s\n", mode_str);
02569
02570 lt = localtime(&sbuf.st_mtime);
02571 if (lt) {
02572 strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
02573 } else {
02574 fstrcpy(mode_str, "unknown");
02575 }
02576 d_printf("Modify: %s\n", mode_str);
02577
02578 lt = localtime(&sbuf.st_ctime);
02579 if (lt) {
02580 strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt);
02581 } else {
02582 fstrcpy(mode_str, "unknown");
02583 }
02584 d_printf("Change: %s\n", mode_str);
02585
02586 return 0;
02587 }
02588
02589
02590
02591
02592
02593
02594 static int cmd_chown(void)
02595 {
02596 pstring src;
02597 uid_t uid;
02598 gid_t gid;
02599 pstring buf, buf2, buf3;
02600 struct cli_state *targetcli;
02601 pstring targetname;
02602
02603 pstrcpy(src,cur_dir);
02604
02605 if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
02606 !next_token_nr(NULL,buf2,NULL, sizeof(buf2)) ||
02607 !next_token_nr(NULL,buf3,NULL, sizeof(buf3))) {
02608 d_printf("chown uid gid file\n");
02609 return 1;
02610 }
02611
02612 uid = (uid_t)atoi(buf);
02613 gid = (gid_t)atoi(buf2);
02614 pstrcat(src,buf3);
02615
02616 if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
02617 d_printf("chown %s: %s\n", src, cli_errstr(cli));
02618 return 1;
02619 }
02620
02621 if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
02622 d_printf("Server doesn't support UNIX CIFS calls.\n");
02623 return 1;
02624 }
02625
02626 if (!cli_unix_chown(targetcli, targetname, uid, gid)) {
02627 d_printf("%s chown file %s uid=%d, gid=%d\n",
02628 cli_errstr(targetcli), src, (int)uid, (int)gid);
02629 return 1;
02630 }
02631
02632 return 0;
02633 }
02634
02635
02636
02637
02638
02639 static int cmd_rename(void)
02640 {
02641 pstring src,dest;
02642 pstring buf,buf2;
02643 struct cli_state *targetcli;
02644 pstring targetsrc;
02645 pstring targetdest;
02646
02647 pstrcpy(src,cur_dir);
02648 pstrcpy(dest,cur_dir);
02649
02650 if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
02651 !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
02652 d_printf("rename <src> <dest>\n");
02653 return 1;
02654 }
02655
02656 pstrcat(src,buf);
02657 pstrcat(dest,buf2);
02658
02659 if ( !cli_resolve_path( "", cli, src, &targetcli, targetsrc ) ) {
02660 d_printf("rename %s: %s\n", src, cli_errstr(cli));
02661 return 1;
02662 }
02663
02664 if ( !cli_resolve_path( "", cli, dest, &targetcli, targetdest ) ) {
02665 d_printf("rename %s: %s\n", dest, cli_errstr(cli));
02666 return 1;
02667 }
02668
02669 if (!cli_rename(targetcli, targetsrc, targetdest)) {
02670 d_printf("%s renaming files %s -> %s \n",
02671 cli_errstr(targetcli),
02672 targetsrc,
02673 targetdest);
02674 return 1;
02675 }
02676
02677 return 0;
02678 }
02679
02680
02681
02682
02683
02684 static int cmd_volume(void)
02685 {
02686 fstring volname;
02687 uint32 serial_num;
02688 time_t create_date;
02689
02690 if (!cli_get_fs_volume_info(cli, volname, &serial_num, &create_date)) {
02691 d_printf("Errr %s getting volume info\n",cli_errstr(cli));
02692 return 1;
02693 }
02694
02695 d_printf("Volume: |%s| serial number 0x%x\n", volname, (unsigned int)serial_num);
02696 return 0;
02697 }
02698
02699
02700
02701
02702
02703 static int cmd_hardlink(void)
02704 {
02705 pstring src,dest;
02706 pstring buf,buf2;
02707 struct cli_state *targetcli;
02708 pstring targetname;
02709
02710 pstrcpy(src,cur_dir);
02711 pstrcpy(dest,cur_dir);
02712
02713 if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) ||
02714 !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) {
02715 d_printf("hardlink <src> <dest>\n");
02716 return 1;
02717 }
02718
02719 pstrcat(src,buf);
02720 pstrcat(dest,buf2);
02721
02722 if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
02723 d_printf("hardlink %s: %s\n", src, cli_errstr(cli));
02724 return 1;
02725 }
02726
02727 if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
02728 d_printf("Server doesn't support UNIX CIFS calls.\n");
02729 return 1;
02730 }
02731
02732 if (!cli_nt_hardlink(targetcli, targetname, dest)) {
02733 d_printf("%s doing an NT hard link of files\n",cli_errstr(targetcli));
02734 return 1;
02735 }
02736
02737 return 0;
02738 }
02739
02740
02741
02742
02743
02744 static int cmd_prompt(void)
02745 {
02746 prompt = !prompt;
02747 DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
02748
02749 return 1;
02750 }
02751
02752
02753
02754
02755
02756 static int cmd_newer(void)
02757 {
02758 pstring buf;
02759 BOOL ok;
02760 SMB_STRUCT_STAT sbuf;
02761
02762 ok = next_token_nr(NULL,buf,NULL,sizeof(buf));
02763 if (ok && (sys_stat(buf,&sbuf) == 0)) {
02764 newer_than = sbuf.st_mtime;
02765 DEBUG(1,("Getting files newer than %s",
02766 time_to_asc(newer_than)));
02767 } else {
02768 newer_than = 0;
02769 }
02770
02771 if (ok && newer_than == 0) {
02772 d_printf("Error setting newer-than time\n");
02773 return 1;
02774 }
02775
02776 return 0;
02777 }
02778
02779
02780
02781
02782
02783 static int cmd_archive(void)
02784 {
02785 pstring buf;
02786
02787 if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
02788 archive_level = atoi(buf);
02789 } else
02790 d_printf("Archive level is %d\n",archive_level);
02791
02792 return 0;
02793 }
02794
02795
02796
02797
02798
02799 static int cmd_lowercase(void)
02800 {
02801 lowercase = !lowercase;
02802 DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
02803
02804 return 0;
02805 }
02806
02807
02808
02809
02810
02811 static int cmd_setcase(void)
02812 {
02813 BOOL orig_case_sensitive = cli_set_case_sensitive(cli, False);
02814
02815 cli_set_case_sensitive(cli, !orig_case_sensitive);
02816 DEBUG(2,("filename case sensitivity is now %s\n",!orig_case_sensitive ?
02817 "on":"off"));
02818
02819 return 0;
02820 }
02821
02822
02823
02824
02825
02826 static int cmd_showacls(void)
02827 {
02828 showacls = !showacls;
02829 DEBUG(2,("showacls is now %s\n",showacls?"on":"off"));
02830
02831 if (!ctx && showacls)
02832 ctx = talloc_init("smbclient:showacls");
02833 if (!ctx) {
02834 DEBUG( 0, ("cmd_showacls() out of memory. talloc_init() failed.\n"));
02835 }
02836
02837 return 0;
02838 }
02839
02840
02841
02842
02843
02844
02845 static int cmd_recurse(void)
02846 {
02847 recurse = !recurse;
02848 DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
02849
02850 return 0;
02851 }
02852
02853
02854
02855
02856
02857 static int cmd_translate(void)
02858 {
02859 translation = !translation;
02860 DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
02861 translation?"on":"off"));
02862
02863 return 0;
02864 }
02865
02866
02867
02868
02869
02870 static int cmd_lcd(void)
02871 {
02872 pstring buf;
02873 pstring d;
02874
02875 if (next_token_nr(NULL,buf,NULL,sizeof(buf)))
02876 chdir(buf);
02877 DEBUG(2,("the local directory is now %s\n",sys_getwd(d)));
02878
02879 return 0;
02880 }
02881
02882
02883
02884
02885
02886 static int cmd_reget(void)
02887 {
02888 pstring local_name;
02889 pstring remote_name;
02890 char *p;
02891
02892 pstrcpy(remote_name, cur_dir);
02893
02894 p = remote_name + strlen(remote_name);
02895
02896 if (!next_token_nr(NULL, p, NULL, sizeof(remote_name) - strlen(remote_name))) {
02897 d_printf("reget <filename>\n");
02898 return 1;
02899 }
02900 pstrcpy(local_name, p);
02901 clean_name(remote_name);
02902
02903 next_token_nr(NULL, local_name, NULL, sizeof(local_name));
02904
02905 return do_get(remote_name, local_name, True);
02906 }
02907
02908
02909
02910
02911
02912 static int cmd_reput(void)
02913 {
02914 pstring local_name;
02915 pstring remote_name;
02916 pstring buf;
02917 char *p = buf;
02918 SMB_STRUCT_STAT st;
02919
02920 pstrcpy(remote_name, cur_dir);
02921
02922 if (!next_token_nr(NULL, p, NULL, sizeof(buf))) {
02923 d_printf("reput <filename>\n");
02924 return 1;
02925 }
02926 pstrcpy(local_name, p);
02927
02928 if (!file_exist(local_name, &st)) {
02929 d_printf("%s does not exist\n", local_name);
02930 return 1;
02931 }
02932
02933 if (next_token_nr(NULL, p, NULL, sizeof(buf)))
02934 pstrcat(remote_name, p);
02935 else
02936 pstrcat(remote_name, local_name);
02937
02938 clean_name(remote_name);
02939
02940 return do_put(remote_name, local_name, True);
02941 }
02942
02943
02944
02945
02946
02947 static void browse_fn(const char *name, uint32 m,
02948 const char *comment, void *state)
02949 {
02950 fstring typestr;
02951
02952 *typestr=0;
02953
02954 switch (m & 7)
02955 {
02956 case STYPE_DISKTREE:
02957 fstrcpy(typestr,"Disk"); break;
02958 case STYPE_PRINTQ:
02959 fstrcpy(typestr,"Printer"); break;
02960 case STYPE_DEVICE:
02961 fstrcpy(typestr,"Device"); break;
02962 case STYPE_IPC:
02963 fstrcpy(typestr,"IPC"); break;
02964 }
02965
02966
02967
02968 if (!grepable) {
02969 d_printf("\t%-15s %-10.10s%s\n",
02970 name,typestr,comment);
02971 } else {
02972 d_printf ("%s|%s|%s\n",typestr,name,comment);
02973 }
02974 }
02975
02976 static BOOL browse_host_rpc(BOOL sort)
02977 {
02978 NTSTATUS status;
02979 struct rpc_pipe_client *pipe_hnd;
02980 TALLOC_CTX *mem_ctx;
02981 ENUM_HND enum_hnd;
02982 WERROR werr;
02983 SRV_SHARE_INFO_CTR ctr;
02984 int i;
02985
02986 mem_ctx = talloc_new(NULL);
02987 if (mem_ctx == NULL) {
02988 DEBUG(0, ("talloc_new failed\n"));
02989 return False;
02990 }
02991
02992 init_enum_hnd(&enum_hnd, 0);
02993
02994 pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
02995
02996 if (pipe_hnd == NULL) {
02997 DEBUG(10, ("Could not connect to srvsvc pipe: %s\n",
02998 nt_errstr(status)));
02999 TALLOC_FREE(mem_ctx);
03000 return False;
03001 }
03002
03003 werr = rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, 1, &ctr,
03004 0xffffffff, &enum_hnd);
03005
03006 if (!W_ERROR_IS_OK(werr)) {
03007 TALLOC_FREE(mem_ctx);
03008 cli_rpc_pipe_close(pipe_hnd);
03009 return False;
03010 }
03011
03012 for (i=0; i<ctr.num_entries; i++) {
03013 SRV_SHARE_INFO_1 *info = &ctr.share.info1[i];
03014 char *name, *comment;
03015 name = rpcstr_pull_unistr2_talloc(
03016 mem_ctx, &info->info_1_str.uni_netname);
03017 comment = rpcstr_pull_unistr2_talloc(
03018 mem_ctx, &info->info_1_str.uni_remark);
03019 browse_fn(name, info->info_1.type, comment, NULL);
03020 }
03021
03022 TALLOC_FREE(mem_ctx);
03023 cli_rpc_pipe_close(pipe_hnd);
03024 return True;
03025 }
03026
03027
03028
03029
03030
03031 static BOOL browse_host(BOOL sort)
03032 {
03033 int ret;
03034 if (!grepable) {
03035 d_printf("\n\tSharename Type Comment\n");
03036 d_printf("\t--------- ---- -------\n");
03037 }
03038
03039 if (browse_host_rpc(sort)) {
03040 return True;
03041 }
03042
03043 if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1)
03044 d_printf("Error returning browse list: %s\n", cli_errstr(cli));
03045
03046 return (ret != -1);
03047 }
03048
03049
03050
03051
03052
03053 static void server_fn(const char *name, uint32 m,
03054 const char *comment, void *state)
03055 {
03056
03057 if (!grepable){
03058 d_printf("\t%-16s %s\n", name, comment);
03059 } else {
03060 d_printf("%s|%s|%s\n",(char *)state, name, comment);
03061 }
03062 }
03063
03064
03065
03066
03067
03068 static BOOL list_servers(const char *wk_grp)
03069 {
03070 fstring state;
03071
03072 if (!cli->server_domain)
03073 return False;
03074
03075 if (!grepable) {
03076 d_printf("\n\tServer Comment\n");
03077 d_printf("\t--------- -------\n");
03078 };
03079 fstrcpy( state, "Server" );
03080 cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn,
03081 state);
03082
03083 if (!grepable) {
03084 d_printf("\n\tWorkgroup Master\n");
03085 d_printf("\t--------- -------\n");
03086 };
03087
03088 fstrcpy( state, "Workgroup" );
03089 cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM,
03090 server_fn, state);
03091 return True;
03092 }
03093
03094
03095
03096
03097
03098 static int cmd_vuid(void)
03099 {
03100 fstring buf;
03101
03102 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
03103 d_printf("Current VUID is %d\n", cli->vuid);
03104 return 0;
03105 }
03106
03107 cli->vuid = atoi(buf);
03108 return 0;
03109 }
03110
03111
03112
03113
03114
03115 static int cmd_logon(void)
03116 {
03117 pstring l_username, l_password;
03118 pstring buf,buf2;
03119
03120 if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
03121 d_printf("logon <username> [<password>]\n");
03122 return 0;
03123 }
03124
03125 pstrcpy(l_username, buf);
03126
03127 if (!next_token_nr(NULL,buf2,NULL,sizeof(buf)))
03128 {
03129 char *pass = getpass("Password: ");
03130 if (pass)
03131 pstrcpy(l_password, pass);
03132 }
03133 else
03134 pstrcpy(l_password, buf2);
03135
03136 if (!NT_STATUS_IS_OK(cli_session_setup(cli, l_username,
03137 l_password, strlen(l_password),
03138 l_password, strlen(l_password),
03139 lp_workgroup()))) {
03140 d_printf("session setup failed: %s\n", cli_errstr(cli));
03141 return -1;
03142 }
03143
03144 d_printf("Current VUID is %d\n", cli->vuid);
03145 return 0;
03146 }
03147
03148
03149
03150
03151
03152
03153 static int cmd_list_connect(void)
03154 {
03155 cli_cm_display();
03156
03157 return 0;
03158 }
03159
03160
03161
03162
03163
03164 static int cmd_show_connect( void )
03165 {
03166 struct cli_state *targetcli;
03167 pstring targetpath;
03168
03169 if ( !cli_resolve_path( "", cli, cur_dir, &targetcli, targetpath ) ) {
03170 d_printf("showconnect %s: %s\n", cur_dir, cli_errstr(cli));
03171 return 1;
03172 }
03173
03174 d_printf("//%s/%s\n", targetcli->desthost, targetcli->share);
03175 return 0;
03176 }
03177
03178
03179
03180 #define COMPL_NONE 0
03181 #define COMPL_REMOTE 1
03182 #define COMPL_LOCAL 2
03183
03184
03185
03186
03187
03188
03189 static struct
03190 {
03191 const char *name;
03192 int (*fn)(void);
03193 const char *description;
03194 char compl_args[2];
03195 } commands[] = {
03196 {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
03197 {"altname",cmd_altname,"<file> show alt name",{COMPL_NONE,COMPL_NONE}},
03198 {"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}},
03199 {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}},
03200 {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}},
03201 {"case_sensitive",cmd_setcase,"toggle the case sensitive flag to server",{COMPL_NONE,COMPL_NONE}},
03202 {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},
03203 {"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_REMOTE}},
03204 {"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_REMOTE}},
03205 {"close",cmd_close,"<fid> close a file given a fid",{COMPL_REMOTE,COMPL_REMOTE}},
03206 {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
03207 {"dir",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
03208 {"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
03209 {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
03210 {"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
03211 {"getfacl",cmd_getfacl,"<file name> get the POSIX ACL on a file (UNIX extensions only)",{COMPL_REMOTE,COMPL_LOCAL}},
03212 {"hardlink",cmd_hardlink,"<src> <dest> create a Windows hard link",{COMPL_REMOTE,COMPL_REMOTE}},
03213 {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
03214 {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
03215 {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}},
03216 {"link",cmd_link,"<oldname> <newname> create a UNIX hard link",{COMPL_REMOTE,COMPL_REMOTE}},
03217 {"lock",cmd_lock,"lock <fnum> [r|w] <hex-start> <hex-len> : set a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}},
03218 {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}},
03219 {"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
03220 {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
03221 {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
03222 {"mget",cmd_mget,"<mask> get all the matching files",{COMPL_REMOTE,COMPL_NONE}},
03223 {"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
03224 {"more",cmd_more,"<remote name> view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}},
03225 {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}},
03226 {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
03227 {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
03228 {"posix", cmd_posix, "turn on all POSIX capabilities", {COMPL_REMOTE,COMPL_NONE}},
03229 {"posix_open",cmd_posix_open,"<name> 0<mode> open_flags mode open a file using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
03230 {"posix_mkdir",cmd_posix_mkdir,"<name> 0<mode> creates a directory using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
03231 {"posix_rmdir",cmd_posix_rmdir,"<name> removes a directory using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
03232 {"posix_unlink",cmd_posix_unlink,"<name> removes a file using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
03233 {"print",cmd_print,"<file name> print a file",{COMPL_NONE,COMPL_NONE}},
03234 {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}},
03235 {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}},
03236 {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}},
03237 {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
03238 {"queue",cmd_queue,"show the print queue",{COMPL_NONE,COMPL_NONE}},
03239 {"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
03240 {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
03241 {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},
03242 {"reget",cmd_reget,"<remote name> [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}},
03243 {"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}},
03244 {"reput",cmd_reput,"<local name> [remote name] put a file restarting at end of remote file",{COMPL_LOCAL,COMPL_REMOTE}},
03245 {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
03246 {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
03247 {"showacls",cmd_showacls,"toggle if ACLs are shown or not",{COMPL_NONE,COMPL_NONE}},
03248 {"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
03249 {"stat",cmd_stat,"filename Do a UNIX extensions stat call on a file",{COMPL_REMOTE,COMPL_REMOTE}},
03250 {"symlink",cmd_symlink,"<oldname> <newname> create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}},
03251 {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
03252 {"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
03253 {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
03254 {"unlock",cmd_unlock,"unlock <fnum> <hex-start> <hex-len> : remove a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}},
03255 {"volume",cmd_volume,"print the volume name",{COMPL_NONE,COMPL_NONE}},
03256 {"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}},
03257 {"wdel",cmd_wdel,"<attrib> <mask> wildcard delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
03258 {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}},
03259 {"listconnect",cmd_list_connect,"list open connections",{COMPL_NONE,COMPL_NONE}},
03260 {"showconnect",cmd_show_connect,"display the current active connection",{COMPL_NONE,COMPL_NONE}},
03261
03262
03263 {"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
03264 {NULL,NULL,NULL,{COMPL_NONE,COMPL_NONE}}
03265 };
03266
03267
03268
03269
03270
03271
03272 static int process_tok(pstring tok)
03273 {
03274 int i = 0, matches = 0;
03275 int cmd=0;
03276 int tok_len = strlen(tok);
03277
03278 while (commands[i].fn != NULL) {
03279 if (strequal(commands[i].name,tok)) {
03280 matches = 1;
03281 cmd = i;
03282 break;
03283 } else if (strnequal(commands[i].name, tok, tok_len)) {
03284 matches++;
03285 cmd = i;
03286 }
03287 i++;
03288 }
03289
03290 if (matches == 0)
03291 return(-1);
03292 else if (matches == 1)
03293 return(cmd);
03294 else
03295 return(-2);
03296 }
03297
03298
03299
03300
03301
03302 static int cmd_help(void)
03303 {
03304 int i=0,j;
03305 pstring buf;
03306
03307 if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
03308 if ((i = process_tok(buf)) >= 0)
03309 d_printf("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description);
03310 } else {
03311 while (commands[i].description) {
03312 for (j=0; commands[i].description && (j<5); j++) {
03313 d_printf("%-15s",commands[i].name);
03314 i++;
03315 }
03316 d_printf("\n");
03317 }
03318 }
03319 return 0;
03320 }
03321
03322
03323
03324
03325
03326 static int process_command_string(char *cmd)
03327 {
03328 pstring line;
03329 const char *ptr;
03330 int rc = 0;
03331
03332
03333
03334 if (!cli) {
03335 cli = cli_cm_open(desthost, service, True);
03336 if (!cli)
03337 return 0;
03338 }
03339
03340 while (cmd[0] != '\0') {
03341 char *p;
03342 pstring tok;
03343 int i;
03344
03345 if ((p = strchr_m(cmd, ';')) == 0) {
03346 strncpy(line, cmd, 999);
03347 line[1000] = '\0';
03348 cmd += strlen(cmd);
03349 } else {
03350 if (p - cmd > 999)
03351 p = cmd + 999;
03352 strncpy(line, cmd, p - cmd);
03353 line[p - cmd] = '\0';
03354 cmd = p + 1;
03355 }
03356
03357
03358 ptr = line;
03359 if (!next_token_nr(&ptr,tok,NULL,sizeof(tok))) continue;
03360
03361 if ((i = process_tok(tok)) >= 0) {
03362 rc = commands[i].fn();
03363 } else if (i == -2) {
03364 d_printf("%s: command abbreviation ambiguous\n",tok);
03365 } else {
03366 d_printf("%s: command not found\n",tok);
03367 }
03368 }
03369
03370 return rc;
03371 }
03372
03373 #define MAX_COMPLETIONS 100
03374
03375 typedef struct {
03376 pstring dirmask;
03377 char **matches;
03378 int count, samelen;
03379 const char *text;
03380 int len;
03381 } completion_remote_t;
03382
03383 static void completion_remote_filter(const char *mnt, file_info *f, const char *mask, void *state)
03384 {
03385 completion_remote_t *info = (completion_remote_t *)state;
03386
03387 if ((info->count < MAX_COMPLETIONS - 1) && (strncmp(info->text, f->name, info->len) == 0) && (strcmp(f->name, ".") != 0) && (strcmp(f->name, "..") != 0)) {
03388 if ((info->dirmask[0] == 0) && !(f->mode & aDIR))
03389 info->matches[info->count] = SMB_STRDUP(f->name);
03390 else {
03391 pstring tmp;
03392
03393 if (info->dirmask[0] != 0)
03394 pstrcpy(tmp, info->dirmask);
03395 else
03396 tmp[0] = 0;
03397 pstrcat(tmp, f->name);
03398 if (f->mode & aDIR)
03399 pstrcat(tmp, "/");
03400 info->matches[info->count] = SMB_STRDUP(tmp);
03401 }
03402 if (info->matches[info->count] == NULL)
03403 return;
03404 if (f->mode & aDIR)
03405 smb_readline_ca_char(0);
03406
03407 if (info->count == 1)
03408 info->samelen = strlen(info->matches[info->count]);
03409 else
03410 while (strncmp(info->matches[info->count], info->matches[info->count-1], info->samelen) != 0)
03411 info->samelen--;
03412 info->count++;
03413 }
03414 }
03415
03416 static char **remote_completion(const char *text, int len)
03417 {
03418 pstring dirmask;
03419 int i;
03420 completion_remote_t info = { "", NULL, 1, 0, NULL, 0 };
03421
03422
03423
03424 info.samelen = len;
03425 info.text = text;
03426 info.len = len;
03427
03428 if (len >= MIN(PATH_MAX,sizeof(pstring))) {
03429 return(NULL);
03430 }
03431
03432 info.matches = SMB_MALLOC_ARRAY(char *,MAX_COMPLETIONS);
03433 if (!info.matches) {
03434 return NULL;
03435 }
03436
03437
03438
03439
03440
03441
03442 info.matches[0] = NULL;
03443 info.count = 1;
03444
03445 for (i = len-1; i >= 0; i--) {
03446 if ((text[i] == '/') || (text[i] == CLI_DIRSEP_CHAR)) {
03447 break;
03448 }
03449 }
03450
03451 info.text = text+i+1;
03452 info.samelen = info.len = len-i-1;
03453
03454 if (i > 0) {
03455 strncpy(info.dirmask, text, i+1);
03456 info.dirmask[i+1] = 0;
03457 pstr_sprintf(dirmask, "%s%*s*", cur_dir, i-1, text);
03458 } else {
03459 pstr_sprintf(dirmask, "%s*", cur_dir);
03460 }
03461
03462 if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0)
03463 goto cleanup;
03464
03465 if (info.count == 1) {
03466
03467
03468
03469
03470
03471 SAFE_FREE(info.matches[0]);
03472 SAFE_FREE(info.matches);
03473 return NULL;
03474 }
03475
03476 if (info.count == 2) {
03477
03478
03479
03480
03481
03482
03483 info.matches[0] = info.matches[1];
03484 info.matches[1] = NULL;
03485 info.count -= 1;
03486 return info.matches;
03487 }
03488
03489
03490
03491
03492
03493
03494 info.matches[0] = SMB_STRNDUP(info.matches[1], info.samelen);
03495 info.matches[info.count] = NULL;
03496 return info.matches;
03497
03498 cleanup:
03499 for (i = 0; i < info.count; i++)
03500 free(info.matches[i]);
03501 free(info.matches);
03502 return NULL;
03503 }
03504
03505 static char **completion_fn(const char *text, int start, int end)
03506 {
03507 smb_readline_ca_char(' ');
03508
03509 if (start) {
03510 const char *buf, *sp;
03511 int i;
03512 char compl_type;
03513
03514 buf = smb_readline_get_line_buffer();
03515 if (buf == NULL)
03516 return NULL;
03517
03518 sp = strchr(buf, ' ');
03519 if (sp == NULL)
03520 return NULL;
03521
03522 for (i = 0; commands[i].name; i++) {
03523 if ((strncmp(commands[i].name, buf, sp - buf) == 0) &&
03524 (commands[i].name[sp - buf] == 0)) {
03525 break;
03526 }
03527 }
03528 if (commands[i].name == NULL)
03529 return NULL;
03530
03531 while (*sp == ' ')
03532 sp++;
03533
03534 if (sp == (buf + start))
03535 compl_type = commands[i].compl_args[0];
03536 else
03537 compl_type = commands[i].compl_args[1];
03538
03539 if (compl_type == COMPL_REMOTE)
03540 return remote_completion(text, end - start);
03541 else
03542 return NULL;
03543 } else {
03544 char **matches;
03545 int i, len, samelen = 0, count=1;
03546
03547 matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
03548 if (!matches) {
03549 return NULL;
03550 }
03551 matches[0] = NULL;
03552
03553 len = strlen(text);
03554 for (i=0;commands[i].fn && count < MAX_COMPLETIONS-1;i++) {
03555 if (strncmp(text, commands[i].name, len) == 0) {
03556 matches[count] = SMB_STRDUP(commands[i].name);
03557 if (!matches[count])
03558 goto cleanup;
03559 if (count == 1)
03560 samelen = strlen(matches[count]);
03561 else
03562 while (strncmp(matches[count], matches[count-1], samelen) != 0)
03563 samelen--;
03564 count++;
03565 }
03566 }
03567
03568 switch (count) {
03569 case 0:
03570 case 1:
03571 goto cleanup;
03572 case 2:
03573 matches[0] = SMB_STRDUP(matches[1]);
03574 break;
03575 default:
03576 matches[0] = (char *)SMB_MALLOC(samelen+1);
03577 if (!matches[0])
03578 goto cleanup;
03579 strncpy(matches[0], matches[1], samelen);
03580 matches[0][samelen] = 0;
03581 }
03582 matches[count] = NULL;
03583 return matches;
03584
03585 cleanup:
03586 for (i = 0; i < count; i++)
03587 free(matches[i]);
03588
03589 free(matches);
03590 return NULL;
03591 }
03592 }
03593
03594
03595
03596
03597
03598 static void readline_callback(void)
03599 {
03600 fd_set fds;
03601 struct timeval timeout;
03602 static time_t last_t;
03603 time_t t;
03604
03605 t = time(NULL);
03606
03607 if (t - last_t < 5)
03608 return;
03609
03610 last_t = t;
03611
03612 again:
03613
03614 if (cli->fd == -1)
03615 return;
03616
03617 FD_ZERO(&fds);
03618 FD_SET(cli->fd,&fds);
03619
03620 timeout.tv_sec = 0;
03621 timeout.tv_usec = 0;
03622 sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
03623
03624
03625
03626
03627
03628 if (FD_ISSET(cli->fd,&fds)) {
03629 if (!receive_smb(cli->fd,cli->inbuf,cli->bufsize,0)) {
03630 DEBUG(0, ("Read from server failed, maybe it closed the "
03631 "connection\n"));
03632 return;
03633 }
03634 goto again;
03635 }
03636
03637
03638 {
03639 unsigned char garbage[16];
03640 memset(garbage, 0xf0, sizeof(garbage));
03641 cli_echo(cli, garbage, sizeof(garbage));
03642 }
03643 }
03644
03645
03646
03647
03648
03649 static int process_stdin(void)
03650 {
03651 const char *ptr;
03652 int rc = 0;
03653
03654 while (1) {
03655 pstring tok;
03656 pstring the_prompt;
03657 char *cline;
03658 pstring line;
03659 int i;
03660
03661
03662 slprintf(the_prompt, sizeof(the_prompt)-1, "smb: %s> ", cur_dir);
03663 cline = smb_readline(the_prompt, readline_callback, completion_fn);
03664
03665 if (!cline) break;
03666
03667 pstrcpy(line, cline);
03668
03669
03670 if (*line == '!') {
03671 system(line + 1);
03672 continue;
03673 }
03674
03675
03676 ptr = line;
03677 if (!next_token_nr(&ptr,tok,NULL,sizeof(tok))) continue;
03678
03679 if ((i = process_tok(tok)) >= 0) {
03680 rc = commands[i].fn();
03681 } else if (i == -2) {
03682 d_printf("%s: command abbreviation ambiguous\n",tok);
03683 } else {
03684 d_printf("%s: command not found\n",tok);
03685 }
03686 }
03687 return rc;
03688 }
03689
03690
03691
03692
03693
03694 static int process(char *base_directory)
03695 {
03696 int rc = 0;
03697
03698 cli = cli_cm_open(desthost, service, True);
03699 if (!cli) {
03700 return 1;
03701 }
03702
03703 if (*base_directory) {
03704 rc = do_cd(base_directory);
03705 if (rc) {
03706 cli_cm_shutdown();
03707 return rc;
03708 }
03709 }
03710
03711 if (cmdstr) {
03712 rc = process_command_string(cmdstr);
03713 } else {
03714 process_stdin();
03715 }
03716
03717 cli_cm_shutdown();
03718 return rc;
03719 }
03720
03721
03722
03723
03724
03725 static int do_host_query(char *query_host)
03726 {
03727 cli = cli_cm_open(query_host, "IPC$", True);
03728 if (!cli)
03729 return 1;
03730
03731 browse_host(True);
03732
03733 if (port != 139) {
03734
03735
03736
03737
03738 cli_cm_shutdown();
03739 port = 139;
03740 cli_cm_set_port( 139 );
03741 cli = cli_cm_open(query_host, "IPC$", True);
03742 }
03743
03744 if (cli == NULL) {
03745 d_printf("NetBIOS over TCP disabled -- no workgroup available\n");
03746 return 1;
03747 }
03748
03749 list_servers(lp_workgroup());
03750
03751 cli_cm_shutdown();
03752
03753 return(0);
03754 }
03755
03756
03757
03758
03759
03760 static int do_tar_op(char *base_directory)
03761 {
03762 int ret;
03763
03764
03765 if (!cli) {
03766 cli = cli_cm_open(desthost, service, True);
03767 if (!cli)
03768 return 1;
03769 }
03770
03771 recurse=True;
03772
03773 if (*base_directory) {
03774 ret = do_cd(base_directory);
03775 if (ret) {
03776 cli_cm_shutdown();
03777 return ret;
03778 }
03779 }
03780
03781 ret=process_tar();
03782
03783 cli_cm_shutdown();
03784
03785 return(ret);
03786 }
03787
03788
03789
03790
03791
03792 static int do_message_op(void)
03793 {
03794 struct in_addr ip;
03795 struct nmb_name called, calling;
03796 fstring server_name;
03797 char name_type_hex[10];
03798 int msg_port;
03799 NTSTATUS status;
03800
03801 make_nmb_name(&calling, calling_name, 0x0);
03802 make_nmb_name(&called , desthost, name_type);
03803
03804 fstrcpy(server_name, desthost);
03805 snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
03806 fstrcat(server_name, name_type_hex);
03807
03808 zero_ip(&ip);
03809 if (have_ip)
03810 ip = dest_ip;
03811
03812
03813
03814 msg_port = port ? port : 139;
03815
03816 if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port)) {
03817 d_printf("Connection to %s failed\n", desthost);
03818 return 1;
03819 }
03820
03821 status = cli_connect(cli, server_name, &ip);
03822 if (!NT_STATUS_IS_OK(status)) {
03823 d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status));
03824 return 1;
03825 }
03826
03827 if (!cli_session_request(cli, &calling, &called)) {
03828 d_printf("session request failed\n");
03829 cli_cm_shutdown();
03830 return 1;
03831 }
03832
03833 send_message();
03834 cli_cm_shutdown();
03835
03836 return 0;
03837 }
03838
03839
03840
03841
03842
03843
03844 int main(int argc,char *argv[])
03845 {
03846 pstring base_directory;
03847 int len = 0;
03848 int opt;
03849 pstring query_host;
03850 BOOL message = False;
03851 pstring term_code;
03852 static const char *new_name_resolve_order = NULL;
03853 poptContext pc;
03854 char *p;
03855 int rc = 0;
03856 fstring new_workgroup;
03857 BOOL tar_opt = False;
03858 BOOL service_opt = False;
03859 struct poptOption long_options[] = {
03860 POPT_AUTOHELP
03861
03862 { "name-resolve", 'R', POPT_ARG_STRING, &new_name_resolve_order, 'R', "Use these name resolution services only", "NAME-RESOLVE-ORDER" },
03863 { "message", 'M', POPT_ARG_STRING, NULL, 'M', "Send message", "HOST" },
03864 { "ip-address", 'I', POPT_ARG_STRING, NULL, 'I', "Use this IP to connect to", "IP" },
03865 { "stderr", 'E', POPT_ARG_NONE, NULL, 'E', "Write messages to stderr instead of stdout" },
03866 { "list", 'L', POPT_ARG_STRING, NULL, 'L', "Get a list of shares available on a host", "HOST" },
03867 { "terminal", 't', POPT_ARG_STRING, NULL, 't', "Terminal I/O code {sjis|euc|jis7|jis8|junet|hex}", "CODE" },
03868 { "max-protocol", 'm', POPT_ARG_STRING, NULL, 'm', "Set the max protocol level", "LEVEL" },
03869 { "tar", 'T', POPT_ARG_STRING, NULL, 'T', "Command line tar", "<c|x>IXFqgbNan" },
03870 { "directory", 'D', POPT_ARG_STRING, NULL, 'D', "Start from directory", "DIR" },
03871 { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" },
03872 { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" },
03873 { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" },
03874 { "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" },
03875 POPT_COMMON_SAMBA
03876 POPT_COMMON_CONNECTION
03877 POPT_COMMON_CREDENTIALS
03878 POPT_TABLEEND
03879 };
03880
03881 load_case_tables();
03882
03883 #ifdef KANJI
03884 pstrcpy(term_code, KANJI);
03885 #else
03886 *term_code = 0;
03887 #endif
03888
03889 *query_host = 0;
03890 *base_directory = 0;
03891
03892
03893
03894
03895 set_global_myworkgroup( "" );
03896 set_global_myname( "" );
03897
03898
03899 setup_logging( "smbclient", True );
03900 DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
03901 if ((dbf = x_fdup(x_stderr))) {
03902 x_setbuf( dbf, NULL );
03903 }
03904
03905
03906 pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 0);
03907 poptSetOtherOptionHelp(pc, "service <password>");
03908
03909 in_client = True;
03910
03911 while ((opt = poptGetNextOpt(pc)) != -1) {
03912
03913
03914
03915 if (tar_opt == True) {
03916 while (poptPeekArg(pc)) {
03917 poptGetArg(pc);
03918 }
03919 tar_opt = False;
03920 }
03921
03922
03923 if (!service_opt && poptPeekArg(pc)) {
03924 pstrcpy(service, poptGetArg(pc));
03925 service_opt = True;
03926 }
03927
03928
03929 if (service_opt && (!cmdline_auth_info.got_pass) && poptPeekArg(pc)) {
03930 pstrcpy(cmdline_auth_info.password, poptGetArg(pc));
03931 cmdline_auth_info.got_pass = True;
03932 }
03933
03934 switch (opt) {
03935 case 'M':
03936
03937
03938
03939
03940 name_type = 0x03;
03941 cli_cm_set_dest_name_type( name_type );
03942 pstrcpy(desthost,poptGetOptArg(pc));
03943 if ( port != 139 )
03944 port = 139;
03945 cli_cm_set_port ( 138);
03946 message = True;
03947 break;
03948 case 'I':
03949 {
03950 dest_ip = *interpret_addr2(poptGetOptArg(pc));
03951 if (is_zero_ip(dest_ip))
03952 exit(1);
03953 have_ip = True;
03954
03955 cli_cm_set_dest_ip( dest_ip );
03956 }
03957 break;
03958 case 'E':
03959 if (dbf) {
03960 x_fclose(dbf);
03961 }
03962 dbf = x_stderr;
03963 display_set_stderr();
03964 break;
03965
03966 case 'L':
03967 pstrcpy(query_host, poptGetOptArg(pc));
03968 break;
03969 case 't':
03970 pstrcpy(term_code, poptGetOptArg(pc));
03971 break;
03972 case 'm':
03973 max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol);
03974 break;
03975 case 'T':
03976
03977
03978 {
03979 int i;
03980 for (i = 1; i < argc; i++) {
03981 if (strncmp("-T", argv[i],2)==0)
03982 break;
03983 }
03984 i++;
03985 if (!tar_parseargs(argc, argv, poptGetOptArg(pc), i)) {
03986 poptPrintUsage(pc, stderr, 0);
03987 exit(1);
03988 }
03989 }
03990
03991 tar_opt = True;
03992 break;
03993 case 'D':
03994 pstrcpy(base_directory,poptGetOptArg(pc));
03995 break;
03996 case 'g':
03997 grepable=True;
03998 break;
03999 }
04000 }
04001
04002
04003 if (tar_opt == True) {
04004 while (poptPeekArg(pc)) {
04005 poptGetArg(pc);
04006 }
04007 tar_opt = False;
04008 }
04009
04010
04011 if (!service_opt && poptPeekArg(pc)) {
04012 pstrcpy(service, poptGetArg(pc));
04013 service_opt = True;
04014 }
04015
04016
04017 if (service_opt && (!cmdline_auth_info.got_pass) && poptPeekArg(pc)) {
04018 pstrcpy(cmdline_auth_info.password, poptGetArg(pc));
04019 cmdline_auth_info.got_pass = True;
04020 }
04021
04022
04023
04024 if ( port != 0 )
04025 cli_cm_set_port( port );
04026
04027
04028
04029
04030
04031 AllowDebugChange = False;
04032
04033
04034
04035
04036
04037
04038
04039 fstrcpy( new_workgroup, lp_workgroup() );
04040 pstrcpy( calling_name, global_myname() );
04041
04042 if ( override_logfile )
04043 setup_logging( lp_logfile(), False );
04044
04045 if (!lp_load(dyn_CONFIGFILE,True,False,False,True)) {
04046 fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n",
04047 argv[0], dyn_CONFIGFILE);
04048 }
04049
04050 load_interfaces();
04051
04052 if (service_opt) {
04053
04054 string_replace(service, '/','\\');
04055 if (count_chars(service,'\\') < 3) {
04056 d_printf("\n%s: Not enough '\\' characters in service\n",service);
04057 poptPrintUsage(pc, stderr, 0);
04058 exit(1);
04059 }
04060
04061 len = strlen(service);
04062 while(len > 0 && service[len - 1] == '\\') {
04063 --len;
04064 service[len] = '\0';
04065 }
04066 }
04067
04068 if ( strlen(new_workgroup) != 0 )
04069 set_global_myworkgroup( new_workgroup );
04070
04071 if ( strlen(calling_name) != 0 )
04072 set_global_myname( calling_name );
04073 else
04074 pstrcpy( calling_name, global_myname() );
04075
04076 init_names();
04077
04078 if(new_name_resolve_order)
04079 lp_set_name_resolve_order(new_name_resolve_order);
04080
04081 if (!tar_type && !*query_host && !*service && !message) {
04082 poptPrintUsage(pc, stderr, 0);
04083 exit(1);
04084 }
04085
04086 poptFreeContext(pc);
04087
04088
04089
04090 cli_cm_set_credentials( &cmdline_auth_info );
04091 pstrcpy(username, cmdline_auth_info.username);
04092
04093 DEBUG(3,("Client started (version %s).\n", SAMBA_VERSION_STRING));
04094
04095 if (tar_type) {
04096 if (cmdstr)
04097 process_command_string(cmdstr);
04098 return do_tar_op(base_directory);
04099 }
04100
04101 if (*query_host) {
04102 char *qhost = query_host;
04103 char *slash;
04104
04105 while (*qhost == '\\' || *qhost == '/')
04106 qhost++;
04107
04108 if ((slash = strchr_m(qhost, '/'))
04109 || (slash = strchr_m(qhost, '\\'))) {
04110 *slash = 0;
04111 }
04112
04113 if ((p=strchr_m(qhost, '#'))) {
04114 *p = 0;
04115 p++;
04116 sscanf(p, "%x", &name_type);
04117 cli_cm_set_dest_name_type( name_type );
04118 }
04119
04120 return do_host_query(qhost);
04121 }
04122
04123 if (message) {
04124 return do_message_op();
04125 }
04126
04127 if (process(base_directory)) {
04128 return 1;
04129 }
04130
04131 talloc_destroy( ctx);
04132 return rc;
04133 }