2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1994-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 pstring cur_dir = "\\";
38 pstring password = "";
40 pstring workgroup=WORKGROUP;
41 BOOL got_pass = False;
42 BOOL connect_as_printer = False;
43 BOOL connect_as_ipc = False;
44 extern struct in_addr bcast_ip;
45 static BOOL got_bcast=False;
50 extern pstring user_socket_options;
52 /* 30 second timeout on most commands */
53 #define CLIENT_TIMEOUT (30*1000)
54 #define SHORT_TIMEOUT (5*1000)
56 /* value for unused fid field in trans2 secondary request */
57 #define FID_UNUSED (0xFFFF)
61 int max_protocol = PROTOCOL_NT1;
64 time_t newer_than = 0;
65 int archive_level = 0;
67 extern struct in_addr myip;
69 extern pstring debugf;
70 extern int DEBUGLEVEL;
72 BOOL translation = False;
74 /* clitar bits insert */
75 extern void cmd_tar();
76 extern void cmd_block();
77 extern void cmd_tarmode();
78 extern void cmd_setmode();
81 extern BOOL tar_reset;
82 extern int process_tar();
83 extern int tar_parseargs();
94 int max_xmit = BUFFER_SIZE;
102 BOOL recurse = False;
103 BOOL lowercase = False;
105 BOOL have_ip = False;
107 struct in_addr dest_ip;
109 #define SEPARATORS " \t\n\r"
111 BOOL abort_mget = True;
115 BOOL readbraw_supported = False;
116 BOOL writebraw_supported = False;
118 pstring fileselection = "";
120 extern file_info def_finfo;
123 int get_total_size = 0;
124 int get_total_time_ms = 0;
125 int put_total_size = 0;
126 int put_total_time_ms = 0;
134 extern int coding_system;
135 #define CNV_LANG(s) (coding_system == DOSV_CODE?s:dos_to_unix(s, False))
136 #define CNV_INPUT(s) (coding_system == DOSV_CODE?s:unix_to_dos(s, True))
138 setup_term_code (char *code)
141 new = interpret_coding_system (code, UNKNOWN_CODE);
142 if (new != UNKNOWN_CODE) {
149 #define CNV_LANG(s) dos2unix_format(s,False)
150 #define CNV_INPUT(s) unix2dos_format(s,True)
153 static void send_logout(void );
154 BOOL reopen_connection(char *inbuf,char *outbuf);
155 static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
156 static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
157 static BOOL call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,
158 int *rprcnt,int *rdrcnt,char *param,char *data,
159 char **rparam,char **rdata);
160 static BOOL send_trans_request(char *outbuf,int trans,
161 char *name,int fid,int flags,
162 char *data,char *param,uint16 *setup,
163 int ldata,int lparam,int lsetup,
164 int mdata,int mparam,int msetup);
167 /****************************************************************************
168 setup basics in a outgoing packet
169 ****************************************************************************/
170 void setup_pkt(char *outbuf)
172 SSVAL(outbuf,smb_pid,pid);
173 SSVAL(outbuf,smb_uid,uid);
174 SSVAL(outbuf,smb_mid,mid);
175 if (Protocol > PROTOCOL_CORE)
177 SCVAL(outbuf,smb_flg,0x8);
178 SSVAL(outbuf,smb_flg2,0x1);
182 /****************************************************************************
183 write to a local file with CR/LF->LF translation if appropriate. return the
184 number taken from the buffer. This may not equal the number written.
185 ****************************************************************************/
186 static int writefile(int f, char *b, int n)
191 return(write(f,b,n));
196 if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n')
200 if (write(f, b, 1) != 1)
211 /****************************************************************************
212 read from a file with LF->CR/LF translation if appropriate. return the
213 number read. read approx n bytes.
214 ****************************************************************************/
215 static int readfile(char *b, int size, int n, FILE *f)
220 if (!translation || (size != 1))
221 return(fread(b,size,n,f));
226 if ((c = getc(f)) == EOF)
231 if (c == '\n') /* change all LFs to CR/LF */
244 /****************************************************************************
245 read from a file with print translation. return the number read. read approx n
247 ****************************************************************************/
248 static int printread(FILE *f,char *b,int n)
252 i = readfile(b,1, n-1,f);
261 /****************************************************************************
262 check for existance of a dir
263 ****************************************************************************/
264 static BOOL chkpath(char *path,BOOL report)
267 pstring inbuf,outbuf;
271 trim_string(path2,NULL,"\\");
272 if (!*path2) *path2 = '\\';
274 bzero(outbuf,smb_size);
275 set_message(outbuf,0,4 + strlen(path2),True);
276 SCVAL(outbuf,smb_com,SMBchkpth);
277 SSVAL(outbuf,smb_tid,cnum);
284 send_smb(Client,outbuf);
285 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
287 if (report && CVAL(inbuf,smb_rcls) != 0)
288 DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
290 return(CVAL(inbuf,smb_rcls) == 0);
294 /****************************************************************************
296 ****************************************************************************/
297 static void send_message(char *inbuf,char *outbuf)
304 /* send a SMBsendstrt command */
305 bzero(outbuf,smb_size);
306 set_message(outbuf,0,0,True);
307 CVAL(outbuf,smb_com) = SMBsendstrt;
308 SSVAL(outbuf,smb_tid,cnum);
313 p = skip_string(p,1);
316 p = skip_string(p,1);
318 set_message(outbuf,0,PTR_DIFF(p,smb_buf(outbuf)),False);
320 send_smb(Client,outbuf);
323 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
325 printf("SMBsendstrt failed. (%s)\n",smb_errstr(inbuf));
329 grp_id = SVAL(inbuf,smb_vwv0);
331 printf("Connected. Type your message, ending it with a Control-D\n");
333 while (!feof(stdin) && total_len < 1600)
335 int maxlen = MIN(1600 - total_len,127);
342 for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++)
349 CVAL(outbuf,smb_com) = SMBsendtxt;
351 set_message(outbuf,1,l+3,True);
353 SSVAL(outbuf,smb_vwv0,grp_id);
360 send_smb(Client,outbuf);
363 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
365 printf("SMBsendtxt failed (%s)\n",smb_errstr(inbuf));
372 if (total_len >= 1600)
373 printf("the message was truncated to 1600 bytes ");
375 printf("sent %d bytes ",total_len);
377 printf("(status was %d-%d)\n",CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err));
379 CVAL(outbuf,smb_com) = SMBsendend;
380 set_message(outbuf,1,0,False);
381 SSVAL(outbuf,smb_vwv0,grp_id);
383 send_smb(Client,outbuf);
386 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
388 printf("SMBsendend failed (%s)\n",smb_errstr(inbuf));
395 /****************************************************************************
396 check the space on a device
397 ****************************************************************************/
398 static void do_dskattr(void)
400 pstring inbuf,outbuf;
402 bzero(outbuf,smb_size);
403 set_message(outbuf,0,0,True);
404 CVAL(outbuf,smb_com) = SMBdskattr;
405 SSVAL(outbuf,smb_tid,cnum);
408 send_smb(Client,outbuf);
409 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
411 if (CVAL(inbuf,smb_rcls) != 0)
412 DEBUG(0,("Error in dskattr: %s\n",smb_errstr(inbuf)));
414 DEBUG(0,("\n\t\t%d blocks of size %d. %d blocks available\n",
415 SVAL(inbuf,smb_vwv0),
416 SVAL(inbuf,smb_vwv1)*SVAL(inbuf,smb_vwv2),
417 SVAL(inbuf,smb_vwv3)));
420 /****************************************************************************
422 ****************************************************************************/
423 static void cmd_pwd(void)
425 DEBUG(0,("Current directory is %s",CNV_LANG(service)));
426 DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
430 /****************************************************************************
431 change directory - inner section
432 ****************************************************************************/
433 static void do_cd(char *newdir)
439 /* Save the current directory in case the
440 new directory is invalid */
441 strcpy(saved_dir, cur_dir);
446 if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
447 strcat(cur_dir, "\\");
449 dos_clean_name(cur_dir);
450 strcpy(dname,cur_dir);
451 strcat(cur_dir,"\\");
452 dos_clean_name(cur_dir);
454 if (!strequal(cur_dir,"\\"))
455 if (!chkpath(dname,True))
456 strcpy(cur_dir,saved_dir);
458 strcpy(cd_path,cur_dir);
461 /****************************************************************************
463 ****************************************************************************/
464 static void cmd_cd(char *inbuf,char *outbuf)
468 if (next_token(NULL,buf,NULL))
471 DEBUG(0,("Current directory is %s\n",CNV_LANG(cur_dir)));
475 /****************************************************************************
476 display info about a file
477 ****************************************************************************/
478 static void display_finfo(file_info *finfo)
480 time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
481 DEBUG(0,(" %-30s%7.7s%10d %s",
482 CNV_LANG(finfo->name),
483 attrib_string(finfo->mode),
485 asctime(LocalTime(&t,GMT_TO_LOCAL))));
488 /****************************************************************************
489 do a directory listing, calling fn on each file found
490 ****************************************************************************/
491 void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
493 DEBUG(5,("do_dir(%s,%x,%s)\n",Mask,attribute,BOOLSTR(recurse_dir)));
494 if (Protocol >= PROTOCOL_LANMAN2)
496 if (do_long_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir) > 0)
500 expand_mask(Mask,False);
501 do_short_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir);
505 /*******************************************************************
506 decide if a file should be operated on
507 ********************************************************************/
508 static BOOL do_this_one(file_info *finfo)
510 if (finfo->mode & aDIR) return(True);
512 if (newer_than && finfo->mtime < newer_than)
515 if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH))
521 /****************************************************************************
522 interpret a short filename structure
523 The length of the structure is returned
524 ****************************************************************************/
525 static int interpret_short_filename(char *p,file_info *finfo)
527 finfo->mode = CVAL(p,21);
529 /* this date is converted to GMT by make_unix_date */
530 finfo->ctime = make_unix_date(p+22);
531 finfo->mtime = finfo->atime = finfo->ctime;
532 finfo->size = IVAL(p,26);
533 strcpy(finfo->name,p+30);
535 return(DIR_STRUCT_SIZE);
538 /****************************************************************************
539 interpret a long filename structure - this is mostly guesses at the moment
540 The length of the structure is returned
541 The structure of a long filename depends on the info level. 260 is used
542 by NT and 2 is used by OS/2
543 ****************************************************************************/
544 static int interpret_long_filename(int level,char *p,file_info *finfo)
547 memcpy(finfo,&def_finfo,sizeof(*finfo));
551 case 1: /* OS/2 understands this */
554 /* these dates are converted to GMT by make_unix_date */
555 finfo->ctime = make_unix_date2(p+4);
556 finfo->atime = make_unix_date2(p+8);
557 finfo->mtime = make_unix_date2(p+12);
558 finfo->size = IVAL(p,16);
559 finfo->mode = CVAL(p,24);
560 strcpy(finfo->name,p+27);
562 return(28 + CVAL(p,26));
564 case 2: /* this is what OS/2 uses mostly */
567 /* these dates are converted to GMT by make_unix_date */
568 finfo->ctime = make_unix_date2(p+4);
569 finfo->atime = make_unix_date2(p+8);
570 finfo->mtime = make_unix_date2(p+12);
571 finfo->size = IVAL(p,16);
572 finfo->mode = CVAL(p,24);
573 strcpy(finfo->name,p+31);
575 return(32 + CVAL(p,30));
577 /* levels 3 and 4 are untested */
581 /* these dates are probably like the other ones */
582 finfo->ctime = make_unix_date2(p+8);
583 finfo->atime = make_unix_date2(p+12);
584 finfo->mtime = make_unix_date2(p+16);
585 finfo->size = IVAL(p,20);
586 finfo->mode = CVAL(p,28);
587 strcpy(finfo->name,p+33);
594 /* these dates are probably like the other ones */
595 finfo->ctime = make_unix_date2(p+8);
596 finfo->atime = make_unix_date2(p+12);
597 finfo->mtime = make_unix_date2(p+16);
598 finfo->size = IVAL(p,20);
599 finfo->mode = CVAL(p,28);
600 strcpy(finfo->name,p+37);
604 case 260: /* NT uses this, but also accepts 2 */
609 p += 4; /* next entry offset */
610 p += 4; /* fileindex */
612 /* these dates appear to arrive in a weird way. It seems to
613 be localtime plus the serverzone given in the initial
614 connect. This is GMT when DST is not in effect and one
615 hour from GMT otherwise. Can this really be right??
617 I suppose this could be called kludge-GMT. Is is the GMT
618 you get by using the current DST setting on a different
619 localtime. It will be cheap to calculate, I suppose, as
620 no DST tables will be needed */
622 finfo->ctime = interpret_long_date(p); p += 8;
623 finfo->atime = interpret_long_date(p); p += 8;
624 finfo->mtime = interpret_long_date(p); p += 8; p += 8;
625 finfo->size = IVAL(p,0); p += 8;
626 p += 8; /* alloc size */
627 finfo->mode = CVAL(p,0); p += 4;
628 namelen = IVAL(p,0); p += 4;
629 p += 4; /* EA size */
630 p += 2; /* short name len? */
631 p += 24; /* short name? */
632 StrnCpy(finfo->name,p,namelen);
638 DEBUG(1,("Unknown long filename format %d\n",level));
645 /****************************************************************************
646 act on the files in a dir listing
647 ****************************************************************************/
648 static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir)
651 if (!((finfo->mode & aDIR) == 0 && *fileselection &&
652 !mask_match(finfo->name,fileselection,False,False)) &&
653 !(recurse_dir && (strequal(finfo->name,".") ||
654 strequal(finfo->name,".."))))
656 if (recurse_dir && (finfo->mode & aDIR))
660 strcpy(sav_dir,cur_dir);
661 strcat(cur_dir,finfo->name);
662 strcat(cur_dir,"\\");
663 strcpy(mask2,cur_dir);
666 DEBUG(0,("\n%s\n",CNV_LANG(cur_dir)));
671 do_long_dir(inbuf,outbuf,mask2,attribute,fn,True);
673 do_dir(inbuf,outbuf,mask2,attribute,fn,True);
675 strcpy(cur_dir,sav_dir);
679 if (fn && do_this_one(finfo))
686 /****************************************************************************
687 do a directory listing, calling fn on each file found
688 ****************************************************************************/
689 static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
695 int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
696 int num_received = 0;
698 char *dirlist = NULL;
710 bzero(outbuf,smb_size);
712 set_message(outbuf,2,5 + strlen(mask),True);
714 set_message(outbuf,2,5 + 21,True);
717 if (Protocol >= PROTOCOL_LANMAN1)
718 CVAL(outbuf,smb_com) = SMBffirst;
721 CVAL(outbuf,smb_com) = SMBsearch;
723 SSVAL(outbuf,smb_tid,cnum);
726 SSVAL(outbuf,smb_vwv0,num_asked);
727 SSVAL(outbuf,smb_vwv1,attribute);
748 send_smb(Client,outbuf);
749 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
751 received = SVAL(inbuf,smb_vwv0);
753 DEBUG(5,("dir received %d\n",received));
755 DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
757 if (received <= 0) break;
761 dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
766 p = smb_buf(inbuf) + 3;
768 memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
769 p,received*DIR_STRUCT_SIZE);
771 memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
773 num_received += received;
775 if (CVAL(inbuf,smb_rcls) != 0) break;
779 if (!first && Protocol >= PROTOCOL_LANMAN1)
781 bzero(outbuf,smb_size);
782 CVAL(outbuf,smb_com) = SMBfclose;
784 SSVAL(outbuf,smb_tid,cnum);
798 send_smb(Client,outbuf);
799 receive_smb(Client,inbuf,CLIENT_TIMEOUT,False);
801 if (CVAL(inbuf,smb_rcls) != 0)
802 DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));
807 for (p=dirlist,i=0;i<num_received;i++)
809 p += interpret_short_filename(p,&finfo);
810 display_finfo(&finfo);
813 for (p=dirlist,i=0;i<num_received;i++)
815 p += interpret_short_filename(p,&finfo);
816 dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
819 if (dirlist) free(dirlist);
820 return(num_received);
823 /****************************************************************************
824 receive a SMB trans or trans2 response allocating the necessary memory
825 ****************************************************************************/
826 static BOOL receive_trans_response(char *inbuf,int trans,
827 int *data_len,int *param_len,
828 char **data,char **param)
832 int this_data,this_param;
834 *data_len = *param_len = 0;
836 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
840 if (CVAL(inbuf,smb_com) != trans)
842 DEBUG(0,("Expected %s response, got command 0x%02x\n",
843 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
846 if (CVAL(inbuf,smb_rcls) != 0)
849 /* parse out the lengths */
850 total_data = SVAL(inbuf,smb_tdrcnt);
851 total_param = SVAL(inbuf,smb_tprcnt);
854 *data = Realloc(*data,total_data);
855 *param = Realloc(*param,total_param);
859 this_data = SVAL(inbuf,smb_drcnt);
860 this_param = SVAL(inbuf,smb_prcnt);
862 memcpy(*data + SVAL(inbuf,smb_drdisp),
863 smb_base(inbuf) + SVAL(inbuf,smb_droff),
866 memcpy(*param + SVAL(inbuf,smb_prdisp),
867 smb_base(inbuf) + SVAL(inbuf,smb_proff),
869 *data_len += this_data;
870 *param_len += this_param;
872 /* parse out the total lengths again - they can shrink! */
873 total_data = SVAL(inbuf,smb_tdrcnt);
874 total_param = SVAL(inbuf,smb_tprcnt);
876 if (total_data <= *data_len && total_param <= *param_len)
879 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
883 if (CVAL(inbuf,smb_com) != trans)
885 DEBUG(0,("Expected %s response, got command 0x%02x\n",
886 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
889 if (CVAL(inbuf,smb_rcls) != 0)
896 /****************************************************************************
897 do a directory listing, calling fn on each file found. Use the TRANSACT2
898 call for long filenames
899 ****************************************************************************/
900 static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
902 int max_matches = 512;
903 int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
908 char *dirlist = NULL;
910 int total_received = 0;
912 char *resp_data=NULL;
913 char *resp_param=NULL;
914 int resp_data_len = 0;
915 int resp_param_len=0;
917 int ff_resume_key = 0;
918 int ff_searchcount=0;
932 if (loop_count > 200)
934 DEBUG(0,("ERROR: Looping in FIND_NEXT??\n"));
940 setup = TRANSACT2_FINDFIRST;
941 SSVAL(param,0,attribute); /* attribute */
942 SSVAL(param,2,max_matches); /* max count */
943 SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
944 SSVAL(param,6,info_level);
946 strcpy(param+12,mask);
950 setup = TRANSACT2_FINDNEXT;
951 SSVAL(param,0,ff_dir_handle);
952 SSVAL(param,2,max_matches); /* max count */
953 SSVAL(param,4,info_level);
954 SIVAL(param,6,ff_resume_key); /* ff_resume_key */
955 SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
956 strcpy(param+12,mask);
958 DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
959 ff_dir_handle,ff_resume_key,ff_lastname,mask));
961 /* ??? original code added 1 pad byte after param */
963 send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
965 0,12+strlen(mask)+1,1,
968 if (!receive_trans_response(inbuf,SMBtrans2,
969 &resp_data_len,&resp_param_len,
970 &resp_data,&resp_param))
972 DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
976 /* parse out some important return info */
980 ff_dir_handle = SVAL(p,0);
981 ff_searchcount = SVAL(p,2);
983 ff_lastname = SVAL(p,8);
987 ff_searchcount = SVAL(p,0);
989 ff_lastname = SVAL(p,6);
992 if (ff_searchcount == 0)
995 /* point to the data bytes */
998 /* we might need the lastname for continuations */
1005 StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
1006 /* strcpy(mask,p+ff_lastname+94); */
1009 strcpy(mask,p + ff_lastname + 1);
1017 /* and add them to the dirlist pool */
1018 dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
1022 DEBUG(0,("Failed to expand dirlist\n"));
1026 /* put in a length for the last entry, to ensure we can chain entries
1027 into the next packet */
1030 for (p2=p,i=0;i<(ff_searchcount-1);i++)
1031 p2 += interpret_long_filename(info_level,p2,NULL);
1032 SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
1035 /* grab the data for later use */
1036 memcpy(dirlist+dirlist_len,p,resp_data_len);
1037 dirlist_len += resp_data_len;
1039 total_received += ff_searchcount;
1041 if (resp_data) free(resp_data); resp_data = NULL;
1042 if (resp_param) free(resp_param); resp_param = NULL;
1044 DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
1045 ff_searchcount,ff_eos,ff_resume_key));
1051 for (p=dirlist,i=0;i<total_received;i++)
1053 p += interpret_long_filename(info_level,p,&finfo);
1054 display_finfo(&finfo);
1057 for (p=dirlist,i=0;i<total_received;i++)
1059 p += interpret_long_filename(info_level,p,&finfo);
1060 dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
1063 /* free up the dirlist buffer */
1064 if (dirlist) free(dirlist);
1065 return(total_received);
1069 /****************************************************************************
1070 get a directory listing
1071 ****************************************************************************/
1072 static void cmd_dir(char *inbuf,char *outbuf)
1074 int attribute = aDIR | aSYSTEM | aHIDDEN;
1079 strcpy(mask,cur_dir);
1080 if(mask[strlen(mask)-1]!='\\')
1083 if (next_token(NULL,buf,NULL))
1094 do_dir(inbuf,outbuf,mask,attribute,NULL,recurse);
1101 /****************************************************************************
1102 get a file from rname to lname
1103 ****************************************************************************/
1104 static void do_get(char *rname,char *lname,file_info *finfo1)
1109 BOOL newhandle = False;
1110 char *inbuf,*outbuf;
1112 BOOL close_done = False;
1113 BOOL ignore_close_error = False;
1117 struct timeval tp_start;
1118 GetTimeOfDay(&tp_start);
1129 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1130 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1132 if (!inbuf || !outbuf)
1134 DEBUG(0,("out of memory\n"));
1138 bzero(outbuf,smb_size);
1139 set_message(outbuf,15,1 + strlen(rname),True);
1141 CVAL(outbuf,smb_com) = SMBopenX;
1142 SSVAL(outbuf,smb_tid,cnum);
1145 SSVAL(outbuf,smb_vwv0,0xFF);
1146 SSVAL(outbuf,smb_vwv2,1);
1147 SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
1148 SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
1149 SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
1150 SSVAL(outbuf,smb_vwv8,1);
1152 p = smb_buf(outbuf);
1154 p = skip_string(p,1);
1156 /* do a chained openX with a readX? */
1160 DEBUG(3,("Chaining readX wth openX\n"));
1161 SSVAL(outbuf,smb_vwv0,SMBreadX);
1162 SSVAL(outbuf,smb_vwv1,smb_offset(p,outbuf));
1165 SSVAL(p,smb_wct,10);
1166 SSVAL(p,smb_vwv0,0xFF);
1167 SSVAL(p,smb_vwv5,MIN(max_xmit-500,finfo.size));
1168 SSVAL(p,smb_vwv9,MIN(BUFFER_SIZE,finfo.size));
1169 smb_setlen(outbuf,smb_len(outbuf)+11*2+1);
1173 if(!strcmp(lname,"-"))
1174 handle = fileno(stdout);
1177 handle = creat(lname,0644);
1182 DEBUG(0,("Error opening local file %s\n",lname));
1183 free(inbuf);free(outbuf);
1187 send_smb(Client,outbuf);
1188 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1190 if (CVAL(inbuf,smb_rcls) != 0)
1192 if (CVAL(inbuf,smb_rcls) == ERRSRV &&
1193 SVAL(inbuf,smb_err) == ERRnoresource &&
1194 reopen_connection(inbuf,outbuf))
1196 do_get(rname,lname,finfo1);
1199 DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
1202 free(inbuf);free(outbuf);
1206 strcpy(finfo.name,rname);
1210 finfo.mode = SVAL(inbuf,smb_vwv3);
1211 /* these times arrive as LOCAL time, using the DST offset
1212 corresponding to that time, we convert them to GMT */
1213 finfo.mtime = make_unix_date3(inbuf+smb_vwv4);
1214 finfo.atime = finfo.ctime = finfo.mtime;
1215 finfo.size = IVAL(inbuf,smb_vwv6);
1218 DEBUG(3,("file %s attrib 0x%X\n",CNV_LANG(finfo.name),finfo.mode));
1220 fnum = SVAL(inbuf,smb_vwv2);
1222 /* we might have got some data from a chained readX */
1223 if (SVAL(inbuf,smb_vwv0) == SMBreadX)
1225 p = (smb_base(inbuf)+SVAL(inbuf,smb_vwv1)) - smb_wct;
1226 datalen = SVAL(p,smb_vwv5);
1227 dataptr = smb_base(inbuf) + SVAL(p,smb_vwv6);
1236 DEBUG(2,("getting file %s of size %d bytes as %s ",
1237 CNV_LANG(finfo.name),
1241 while (nread < finfo.size && !close_done)
1244 static BOOL can_chain_close = True;
1248 DEBUG(3,("nread=%d max_xmit=%d fsize=%d\n",nread,max_xmit,finfo.size));
1250 /* 3 possible read types. readbraw if a large block is required.
1251 readX + close if not much left and read if neither is supported */
1253 /* we might have already read some data from a chained readX */
1254 if (dataptr && datalen>0)
1257 /* if we can finish now then readX+close */
1258 if (method<0 && can_chain_close && (Protocol >= PROTOCOL_LANMAN1) &&
1259 ((finfo.size - nread) <
1260 (max_xmit - (2*smb_size + 13*SIZEOFWORD + 300))))
1263 /* if we support readraw then use that */
1264 if (method<0 && readbraw_supported)
1267 /* if we can then use readX */
1268 if (method<0 && (Protocol >= PROTOCOL_LANMAN1))
1279 /* use readX + close */
1280 bzero(outbuf,smb_size);
1281 set_message(outbuf,10,0,True);
1282 CVAL(outbuf,smb_com) = SMBreadX;
1283 SSVAL(outbuf,smb_tid,cnum);
1288 CVAL(outbuf,smb_vwv0) = SMBclose;
1289 SSVAL(outbuf,smb_vwv1,smb_offset(smb_buf(outbuf),outbuf));
1292 CVAL(outbuf,smb_vwv0) = 0xFF;
1294 SSVAL(outbuf,smb_vwv2,fnum);
1295 SIVAL(outbuf,smb_vwv3,nread);
1296 SSVAL(outbuf,smb_vwv5,MIN(max_xmit-200,finfo.size - nread));
1297 SSVAL(outbuf,smb_vwv6,0);
1298 SIVAL(outbuf,smb_vwv7,0);
1299 SSVAL(outbuf,smb_vwv9,MIN(BUFFER_SIZE,finfo.size-nread));
1303 p = smb_buf(outbuf);
1310 /* now set the total packet length */
1311 smb_setlen(outbuf,smb_len(outbuf)+9);
1314 send_smb(Client,outbuf);
1315 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1317 if (CVAL(inbuf,smb_rcls) != 0)
1319 DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
1324 SVAL(inbuf,smb_vwv0) != SMBclose)
1326 /* NOTE: WfWg sometimes just ignores the chained
1327 command! This seems to break the spec? */
1328 DEBUG(3,("Rejected chained close?\n"));
1330 can_chain_close = False;
1331 ignore_close_error = True;
1334 datalen = SVAL(inbuf,smb_vwv5);
1335 dataptr = smb_base(inbuf) + SVAL(inbuf,smb_vwv6);
1341 static int readbraw_size = BUFFER_SIZE;
1344 bzero(outbuf,smb_size);
1345 set_message(outbuf,8,0,True);
1346 CVAL(outbuf,smb_com) = SMBreadbraw;
1347 SSVAL(outbuf,smb_tid,cnum);
1349 SSVAL(outbuf,smb_vwv0,fnum);
1350 SIVAL(outbuf,smb_vwv1,nread);
1351 SSVAL(outbuf,smb_vwv3,MIN(finfo.size-nread,readbraw_size));
1352 SSVAL(outbuf,smb_vwv4,0);
1353 SIVALS(outbuf,smb_vwv5,-1);
1354 send_smb(Client,outbuf);
1356 /* Now read the raw data into the buffer and write it */
1357 if(read_smb_length(Client,inbuf,0) == -1) {
1358 DEBUG(0,("Failed to read length in readbraw\n"));
1362 /* Even though this is not an smb message, smb_len
1363 returns the generic length of an smb message */
1364 datalen = smb_len(inbuf);
1368 /* we got a readbraw error */
1369 DEBUG(4,("readbraw error - reducing size\n"));
1370 readbraw_size = (readbraw_size * 9) / 10;
1372 if (readbraw_size < max_xmit)
1374 DEBUG(0,("disabling readbraw\n"));
1375 readbraw_supported = False;
1382 if(read_data(Client,inbuf,datalen) != datalen) {
1383 DEBUG(0,("Failed to read data in readbraw\n"));
1391 /* we've already read some data with a chained readX */
1395 /* use plain read */
1396 bzero(outbuf,smb_size);
1397 set_message(outbuf,5,0,True);
1398 CVAL(outbuf,smb_com) = SMBread;
1399 SSVAL(outbuf,smb_tid,cnum);
1402 SSVAL(outbuf,smb_vwv0,fnum);
1403 SSVAL(outbuf,smb_vwv1,MIN(max_xmit-200,finfo.size - nread));
1404 SIVAL(outbuf,smb_vwv2,nread);
1405 SSVAL(outbuf,smb_vwv4,finfo.size - nread);
1407 send_smb(Client,outbuf);
1408 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1410 if (CVAL(inbuf,smb_rcls) != 0)
1412 DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
1416 datalen = SVAL(inbuf,smb_vwv0);
1417 dataptr = smb_buf(inbuf) + 3;
1421 if (writefile(handle,dataptr,datalen) != datalen)
1423 DEBUG(0,("Error writing local file\n"));
1430 DEBUG(0,("Error reading file %s. Got %d bytes\n",CNV_LANG(rname),nread));
1442 bzero(outbuf,smb_size);
1443 set_message(outbuf,3,0,True);
1444 CVAL(outbuf,smb_com) = SMBclose;
1445 SSVAL(outbuf,smb_tid,cnum);
1448 SSVAL(outbuf,smb_vwv0,fnum);
1449 SIVALS(outbuf,smb_vwv1,-1);
1451 send_smb(Client,outbuf);
1452 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1454 if (!ignore_close_error && CVAL(inbuf,smb_rcls) != 0)
1456 DEBUG(0,("Error %s closing remote file\n",smb_errstr(inbuf)));
1459 free(inbuf);free(outbuf);
1467 if (archive_level >= 2 && (finfo.mode & aARCH)) {
1468 bzero(outbuf,smb_size);
1469 set_message(outbuf,8,strlen(rname)+4,True);
1470 CVAL(outbuf,smb_com) = SMBsetatr;
1471 SSVAL(outbuf,smb_tid,cnum);
1473 SSVAL(outbuf,smb_vwv0,finfo.mode & ~(aARCH));
1474 SIVALS(outbuf,smb_vwv1,0);
1475 p = smb_buf(outbuf);
1481 send_smb(Client,outbuf);
1482 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1486 struct timeval tp_end;
1489 GetTimeOfDay(&tp_end);
1491 (tp_end.tv_sec - tp_start.tv_sec)*1000 +
1492 (tp_end.tv_usec - tp_start.tv_usec)/1000;
1493 get_total_time_ms += this_time;
1494 get_total_size += finfo.size;
1496 DEBUG(2,("(%g kb/s) (average %g kb/s)\n",
1497 finfo.size / (1.024*this_time + 1.0e-4),
1498 get_total_size / (1.024*get_total_time_ms)));
1501 free(inbuf);free(outbuf);
1505 /****************************************************************************
1507 ****************************************************************************/
1508 static void cmd_get(void)
1514 strcpy(rname,cur_dir);
1517 p = rname + strlen(rname);
1519 if (!next_token(NULL,p,NULL)) {
1520 DEBUG(0,("get <filename>\n"));
1524 dos_clean_name(rname);
1526 next_token(NULL,lname,NULL);
1528 do_get(rname,lname,NULL);
1532 /****************************************************************************
1533 do a mget operation on one file
1534 ****************************************************************************/
1535 static void do_mget(file_info *finfo)
1540 if (strequal(finfo->name,".") || strequal(finfo->name,".."))
1545 DEBUG(0,("mget aborted\n"));
1549 if (finfo->mode & aDIR)
1550 sprintf(quest,"Get directory %s? ",CNV_LANG(finfo->name));
1552 sprintf(quest,"Get file %s? ",CNV_LANG(finfo->name));
1554 if (prompt && !yesno(quest)) return;
1556 if (finfo->mode & aDIR)
1558 pstring saved_curdir;
1560 char *inbuf,*outbuf;
1562 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1563 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1565 if (!inbuf || !outbuf)
1567 DEBUG(0,("out of memory\n"));
1571 strcpy(saved_curdir,cur_dir);
1573 strcat(cur_dir,finfo->name);
1574 strcat(cur_dir,"\\");
1576 unix_format(finfo->name);
1579 strlower(finfo->name);
1581 if (!directory_exist(finfo->name,NULL) &&
1582 sys_mkdir(finfo->name,0777) != 0)
1584 DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
1585 strcpy(cur_dir,saved_curdir);
1586 free(inbuf);free(outbuf);
1590 if (sys_chdir(finfo->name) != 0)
1592 DEBUG(0,("failed to chdir to directory %s\n",CNV_LANG(finfo->name)));
1593 strcpy(cur_dir,saved_curdir);
1594 free(inbuf);free(outbuf);
1599 strcpy(mget_mask,cur_dir);
1600 strcat(mget_mask,"*");
1602 do_dir((char *)inbuf,(char *)outbuf,
1603 mget_mask,aSYSTEM | aHIDDEN | aDIR,do_mget,False);
1605 strcpy(cur_dir,saved_curdir);
1606 free(inbuf);free(outbuf);
1610 strcpy(rname,cur_dir);
1611 strcat(rname,finfo->name);
1612 do_get(rname,finfo->name,finfo);
1616 /****************************************************************************
1617 view the file using the pager
1618 ****************************************************************************/
1619 static void cmd_more(void)
1621 fstring rname,lname,tmpname,pager_cmd;
1624 strcpy(rname,cur_dir);
1626 sprintf(tmpname,"/tmp/smbmore.%d",getpid());
1627 strcpy(lname,tmpname);
1629 if (!next_token(NULL,rname+strlen(rname),NULL)) {
1630 DEBUG(0,("more <filename>\n"));
1633 dos_clean_name(rname);
1635 do_get(rname,lname,NULL);
1637 pager=getenv("PAGER");
1638 sprintf(pager_cmd,"%s %s",(pager? pager:PAGER), tmpname);
1645 /****************************************************************************
1647 ****************************************************************************/
1648 static void cmd_mget(char *inbuf,char *outbuf)
1650 int attribute = aSYSTEM | aHIDDEN;
1662 while (next_token(NULL,p,NULL))
1664 strcpy(mget_mask,cur_dir);
1665 if(mget_mask[strlen(mget_mask)-1]!='\\')
1666 strcat(mget_mask,"\\");
1669 strcpy(mget_mask,p);
1671 strcat(mget_mask,p);
1672 do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
1677 strcpy(mget_mask,cur_dir);
1678 if(mget_mask[strlen(mget_mask)-1]!='\\')
1679 strcat(mget_mask,"\\");
1680 strcat(mget_mask,"*");
1681 do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
1685 /****************************************************************************
1686 make a directory of name "name"
1687 ****************************************************************************/
1688 static BOOL do_mkdir(char *name)
1691 char *inbuf,*outbuf;
1693 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1694 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1696 if (!inbuf || !outbuf)
1698 DEBUG(0,("out of memory\n"));
1702 bzero(outbuf,smb_size);
1703 set_message(outbuf,0,2 + strlen(name),True);
1705 CVAL(outbuf,smb_com) = SMBmkdir;
1706 SSVAL(outbuf,smb_tid,cnum);
1710 p = smb_buf(outbuf);
1714 send_smb(Client,outbuf);
1715 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1717 if (CVAL(inbuf,smb_rcls) != 0)
1719 DEBUG(0,("%s making remote directory %s\n",
1720 smb_errstr(inbuf),CNV_LANG(name)));
1722 free(inbuf);free(outbuf);
1726 free(inbuf);free(outbuf);
1731 /****************************************************************************
1733 ****************************************************************************/
1734 static void cmd_mkdir(char *inbuf,char *outbuf)
1740 strcpy(mask,cur_dir);
1742 if (!next_token(NULL,p,NULL))
1745 DEBUG(0,("mkdir <dirname>\n"));
1757 trim_string(ddir,".",NULL);
1758 p = strtok(ddir,"/\\");
1762 if (!chkpath(ddir2,False))
1767 p = strtok(NULL,"/\\");
1775 /*******************************************************************
1776 write to a file using writebraw
1777 ********************************************************************/
1778 static int smb_writeraw(char *outbuf,int fnum,int pos,char *buf,int n)
1783 bzero(outbuf,smb_size);
1784 bzero(inbuf,smb_size);
1785 set_message(outbuf,Protocol>PROTOCOL_COREPLUS?12:10,0,True);
1787 CVAL(outbuf,smb_com) = SMBwritebraw;
1788 SSVAL(outbuf,smb_tid,cnum);
1791 SSVAL(outbuf,smb_vwv0,fnum);
1792 SSVAL(outbuf,smb_vwv1,n);
1793 SIVAL(outbuf,smb_vwv3,pos);
1794 SSVAL(outbuf,smb_vwv7,1);
1796 send_smb(Client,outbuf);
1798 if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
1801 _smb_setlen(buf-4,n); /* HACK! XXXX */
1803 if (write_socket(Client,buf-4,n+4) != n+4)
1806 if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0) {
1807 DEBUG(0,("Error writing remote file (2)\n"));
1810 return(SVAL(inbuf,smb_vwv0));
1815 /*******************************************************************
1817 ********************************************************************/
1818 static int smb_writefile(char *outbuf,int fnum,int pos,char *buf,int n)
1822 if (writebraw_supported && n > (max_xmit-200))
1823 return(smb_writeraw(outbuf,fnum,pos,buf,n));
1825 bzero(outbuf,smb_size);
1826 bzero(inbuf,smb_size);
1827 set_message(outbuf,5,n + 3,True);
1829 CVAL(outbuf,smb_com) = SMBwrite;
1830 SSVAL(outbuf,smb_tid,cnum);
1833 SSVAL(outbuf,smb_vwv0,fnum);
1834 SSVAL(outbuf,smb_vwv1,n);
1835 SIVAL(outbuf,smb_vwv2,pos);
1836 SSVAL(outbuf,smb_vwv4,0);
1837 CVAL(smb_buf(outbuf),0) = 1;
1838 SSVAL(smb_buf(outbuf),1,n);
1840 memcpy(smb_buf(outbuf)+3,buf,n);
1842 send_smb(Client,outbuf);
1843 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1845 if (CVAL(inbuf,smb_rcls) != 0) {
1846 DEBUG(0,("%s writing remote file\n",smb_errstr(inbuf)));
1849 return(SVAL(inbuf,smb_vwv0));
1854 /****************************************************************************
1856 ****************************************************************************/
1857 static void do_put(char *rname,char *lname,file_info *finfo)
1863 char *inbuf,*outbuf;
1864 time_t close_time = finfo->mtime;
1866 static int maxwrite=0;
1868 struct timeval tp_start;
1869 GetTimeOfDay(&tp_start);
1871 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1872 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1874 if (!inbuf || !outbuf)
1876 DEBUG(0,("out of memory\n"));
1880 bzero(outbuf,smb_size);
1881 set_message(outbuf,3,2 + strlen(rname),True);
1883 if (finfo->mtime == 0 || finfo->mtime == -1)
1884 finfo->mtime = finfo->atime = finfo->ctime = time(NULL);
1886 CVAL(outbuf,smb_com) = SMBcreate;
1887 SSVAL(outbuf,smb_tid,cnum);
1890 SSVAL(outbuf,smb_vwv0,finfo->mode);
1891 put_dos_date3(outbuf,smb_vwv1,finfo->mtime);
1893 p = smb_buf(outbuf);
1897 send_smb(Client,outbuf);
1898 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1900 if (CVAL(inbuf,smb_rcls) != 0)
1902 DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
1904 free(inbuf);free(outbuf);if (buf) free(buf);
1908 f = fopen(lname,"r");
1912 DEBUG(0,("Error opening local file %s\n",lname));
1913 free(inbuf);free(outbuf);
1918 fnum = SVAL(inbuf,smb_vwv0);
1919 if (finfo->size < 0)
1920 finfo->size = file_size(lname);
1922 DEBUG(1,("putting file %s of size %d bytes as %s ",lname,finfo->size,CNV_LANG(rname)));
1925 maxwrite = writebraw_supported?MAX(max_xmit,BUFFER_SIZE):(max_xmit-200);
1927 while (nread < finfo->size)
1932 n = MIN(n,finfo->size - nread);
1934 buf = (char *)Realloc(buf,n+4);
1936 fseek(f,nread,SEEK_SET);
1937 if ((n = readfile(buf+4,1,n,f)) < 1)
1939 DEBUG(0,("Error reading local file\n"));
1943 ret = smb_writefile(outbuf,fnum,nread,buf+4,n);
1947 DEBUG(0,("Error writing file\n"));
1960 bzero(outbuf,smb_size);
1961 set_message(outbuf,3,0,True);
1962 CVAL(outbuf,smb_com) = SMBclose;
1963 SSVAL(outbuf,smb_tid,cnum);
1966 SSVAL(outbuf,smb_vwv0,fnum);
1967 put_dos_date3(outbuf,smb_vwv1,close_time);
1969 send_smb(Client,outbuf);
1970 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1972 if (CVAL(inbuf,smb_rcls) != 0)
1974 DEBUG(0,("%s closing remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
1976 free(inbuf);free(outbuf);
1983 free(inbuf);free(outbuf);
1987 struct timeval tp_end;
1990 GetTimeOfDay(&tp_end);
1992 (tp_end.tv_sec - tp_start.tv_sec)*1000 +
1993 (tp_end.tv_usec - tp_start.tv_usec)/1000;
1994 put_total_time_ms += this_time;
1995 put_total_size += finfo->size;
1997 DEBUG(2,("(%g kb/s) (average %g kb/s)\n",
1998 finfo->size / (1.024*this_time + 1.0e-4),
1999 put_total_size / (1.024*put_total_time_ms)));
2005 /****************************************************************************
2007 ****************************************************************************/
2008 static void cmd_put(void)
2017 strcpy(rname,cur_dir);
2021 if (!next_token(NULL,p,NULL))
2023 DEBUG(0,("put <filename>\n"));
2028 if (next_token(NULL,p,NULL))
2031 strcat(rname,lname);
2033 dos_clean_name(rname);
2037 if (!file_exist(lname,&st)) {
2038 DEBUG(0,("%s does not exist\n",lname));
2041 finfo.mtime = st.st_mtime;
2044 do_put(rname,lname,&finfo);
2047 /****************************************************************************
2048 seek in a directory/file list until you get something that doesn't start with
2050 ****************************************************************************/
2051 static BOOL seek_list(FILE *f,char *name)
2056 if (fscanf(f,"%s",s) != 1) return(False);
2057 trim_string(s,"./",NULL);
2058 if (strncmp(s,name,strlen(name)) != 0)
2069 /****************************************************************************
2070 set the file selection mask
2071 ****************************************************************************/
2072 static void cmd_select(void)
2074 strcpy(fileselection,"");
2075 next_token(NULL,fileselection,NULL);
2079 /****************************************************************************
2081 ****************************************************************************/
2082 static void cmd_mput(void)
2093 while (next_token(NULL,p,NULL))
2100 sprintf(tmpname,"/tmp/ls.smb.%d",(int)getpid());
2102 sprintf(cmd,"find . -name \"%s\" -print > %s",p,tmpname);
2104 sprintf(cmd,"/bin/ls %s > %s",p,tmpname);
2107 f = fopen(tmpname,"r");
2114 if (fscanf(f,"%s",lname) != 1) break;
2115 trim_string(lname,"./",NULL);
2119 /* check if it's a directory */
2120 if (directory_exist(lname,&st))
2122 if (!recurse) continue;
2123 sprintf(quest,"Put directory %s? ",lname);
2124 if (prompt && !yesno(quest))
2127 if (!seek_list(f,lname))
2132 strcpy(rname,cur_dir);
2133 strcat(rname,lname);
2134 if (!do_mkdir(rname))
2137 if (!seek_list(f,lname))
2146 sprintf(quest,"Put file %s? ",lname);
2147 if (prompt && !yesno(quest)) continue;
2149 strcpy(rname,cur_dir);
2150 strcat(rname,lname);
2154 /* null size so do_put knows to ignore it */
2157 /* set the date on the file */
2158 finfo.mtime = st.st_mtime;
2160 do_put(rname,lname,&finfo);
2167 /****************************************************************************
2169 ****************************************************************************/
2170 static void do_cancel(int job)
2172 char *rparam = NULL;
2178 bzero(param,sizeof(param));
2181 SSVAL(p,0,81); /* api number */
2184 p = skip_string(p,1);
2186 p = skip_string(p,1);
2190 if (call_api(PTR_DIFF(p,param),0,
2196 int res = SVAL(rparam,0);
2199 printf("Job %d cancelled\n",job);
2201 printf("Error %d calcelling job %d\n",res,job);
2205 printf("Server refused cancel request\n");
2207 if (rparam) free(rparam);
2208 if (rdata) free(rdata);
2214 /****************************************************************************
2216 ****************************************************************************/
2217 static void cmd_cancel(char *inbuf,char *outbuf )
2222 if (!connect_as_printer)
2224 DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
2225 DEBUG(0,("Trying to cancel print jobs without -P may fail\n"));
2228 if (!next_token(NULL,buf,NULL)) {
2229 printf("cancel <jobid> ...\n");
2235 } while (next_token(NULL,buf,NULL));
2239 /****************************************************************************
2241 ****************************************************************************/
2242 static void cmd_stat(char *inbuf,char *outbuf)
2246 char *resp_data=NULL;
2247 char *resp_param=NULL;
2248 int resp_data_len = 0;
2249 int resp_param_len=0;
2251 uint16 setup = TRANSACT2_QPATHINFO;
2253 if (!next_token(NULL,buf,NULL)) {
2254 printf("stat <file>\n");
2259 SSVAL(param,0,4); /* level */
2264 send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
2266 0,6 + strlen(p)+1,1,
2269 receive_trans_response(inbuf,SMBtrans2,
2270 &resp_data_len,&resp_param_len,
2271 &resp_data,&resp_param);
2273 if (resp_data) free(resp_data); resp_data = NULL;
2274 if (resp_param) free(resp_param); resp_param = NULL;
2278 /****************************************************************************
2280 ****************************************************************************/
2281 static void cmd_print(char *inbuf,char *outbuf )
2290 if (!connect_as_printer)
2292 DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
2293 DEBUG(0,("Trying to print without -P may fail\n"));
2296 if (!next_token(NULL,lname,NULL))
2298 DEBUG(0,("print <filename>\n"));
2302 strcpy(rname,lname);
2303 p = strrchr(rname,'/');
2308 strcpy(rname,tname);
2311 if ((int)strlen(rname) > 14)
2314 if (strequal(lname,"-"))
2317 strcpy(rname,"stdin");
2320 dos_clean_name(rname);
2322 bzero(outbuf,smb_size);
2323 set_message(outbuf,2,2 + strlen(rname),True);
2325 CVAL(outbuf,smb_com) = SMBsplopen;
2326 SSVAL(outbuf,smb_tid,cnum);
2329 SSVAL(outbuf,smb_vwv0,0);
2330 SSVAL(outbuf,smb_vwv1,printmode);
2332 p = smb_buf(outbuf);
2336 send_smb(Client,outbuf);
2337 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2339 if (CVAL(inbuf,smb_rcls) != 0)
2341 DEBUG(0,("%s opening printer for %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
2346 f = fopen(lname,"r");
2349 DEBUG(0,("Error opening local file %s\n",lname));
2354 fnum = SVAL(inbuf,smb_vwv0);
2356 DEBUG(1,("printing file %s as %s\n",lname,CNV_LANG(rname)));
2362 bzero(outbuf,smb_size);
2363 set_message(outbuf,1,3,True);
2365 /* for some strange reason the OS/2 print server can't handle large
2366 packets when printing. weird */
2367 n = MIN(1024,max_xmit-(smb_len(outbuf)+4));
2370 n = printread(f,smb_buf(outbuf)+3,(int)(0.95*n));
2372 n = readfile(smb_buf(outbuf)+3,1,n,f);
2375 DEBUG(0,("read gave %d\n",n));
2379 smb_setlen(outbuf,smb_len(outbuf) + n);
2381 CVAL(outbuf,smb_com) = SMBsplwr;
2382 SSVAL(outbuf,smb_tid,cnum);
2385 SSVAL(outbuf,smb_vwv0,fnum);
2386 SSVAL(outbuf,smb_vwv1,n+3);
2387 CVAL(smb_buf(outbuf),0) = 1;
2388 SSVAL(smb_buf(outbuf),1,n);
2390 send_smb(Client,outbuf);
2391 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2393 if (CVAL(inbuf,smb_rcls) != 0)
2395 DEBUG(0,("%s printing remote file\n",smb_errstr(inbuf)));
2402 DEBUG(2,("%d bytes printed\n",nread));
2404 bzero(outbuf,smb_size);
2405 set_message(outbuf,1,0,True);
2406 CVAL(outbuf,smb_com) = SMBsplclose;
2407 SSVAL(outbuf,smb_tid,cnum);
2410 SSVAL(outbuf,smb_vwv0,fnum);
2412 send_smb(Client,outbuf);
2413 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2415 if (CVAL(inbuf,smb_rcls) != 0)
2417 DEBUG(0,("%s closing print file\n",smb_errstr(inbuf)));
2427 /****************************************************************************
2429 ****************************************************************************/
2430 static void cmd_queue(char *inbuf,char *outbuf )
2435 bzero(outbuf,smb_size);
2436 set_message(outbuf,2,0,True);
2438 CVAL(outbuf,smb_com) = SMBsplretq;
2439 SSVAL(outbuf,smb_tid,cnum);
2442 SSVAL(outbuf,smb_vwv0,32); /* a max of 20 entries is to be shown */
2443 SSVAL(outbuf,smb_vwv1,0); /* the index into the queue */
2445 send_smb(Client,outbuf);
2446 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2448 if (CVAL(inbuf,smb_rcls) != 0)
2450 DEBUG(0,("%s obtaining print queue\n",smb_errstr(inbuf)));
2454 count = SVAL(inbuf,smb_vwv0);
2455 p = smb_buf(inbuf) + 3;
2458 DEBUG(0,("No entries in the print queue\n"));
2465 DEBUG(0,("Job Name Size Status\n"));
2471 case 0x01: sprintf(status,"held or stopped"); break;
2472 case 0x02: sprintf(status,"printing"); break;
2473 case 0x03: sprintf(status,"awaiting print"); break;
2474 case 0x04: sprintf(status,"in intercept"); break;
2475 case 0x05: sprintf(status,"file had error"); break;
2476 case 0x06: sprintf(status,"printer error"); break;
2477 default: sprintf(status,"unknown"); break;
2480 DEBUG(0,("%-6d %-16.16s %-9d %s\n",
2481 SVAL(p,5),p+12,IVAL(p,7),status));
2489 /****************************************************************************
2491 ****************************************************************************/
2492 static void do_del(file_info *finfo)
2495 char *inbuf,*outbuf;
2498 strcpy(mask,cur_dir);
2499 strcat(mask,finfo->name);
2501 if (finfo->mode & aDIR)
2504 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2505 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2507 if (!inbuf || !outbuf)
2509 DEBUG(0,("out of memory\n"));
2513 bzero(outbuf,smb_size);
2514 set_message(outbuf,1,2 + strlen(mask),True);
2516 CVAL(outbuf,smb_com) = SMBunlink;
2517 SSVAL(outbuf,smb_tid,cnum);
2520 SSVAL(outbuf,smb_vwv0,0);
2522 p = smb_buf(outbuf);
2526 send_smb(Client,outbuf);
2527 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2529 if (CVAL(inbuf,smb_rcls) != 0)
2530 DEBUG(0,("%s deleting remote file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
2532 free(inbuf);free(outbuf);
2536 /****************************************************************************
2538 ****************************************************************************/
2539 static void cmd_del(char *inbuf,char *outbuf )
2543 int attribute = aSYSTEM | aHIDDEN;
2548 strcpy(mask,cur_dir);
2550 if (!next_token(NULL,buf,NULL))
2552 DEBUG(0,("del <filename>\n"));
2557 do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_del,False);
2561 /****************************************************************************
2563 ****************************************************************************/
2564 static void cmd_rmdir(char *inbuf,char *outbuf )
2570 strcpy(mask,cur_dir);
2572 if (!next_token(NULL,buf,NULL))
2574 DEBUG(0,("rmdir <dirname>\n"));
2579 bzero(outbuf,smb_size);
2580 set_message(outbuf,0,2 + strlen(mask),True);
2582 CVAL(outbuf,smb_com) = SMBrmdir;
2583 SSVAL(outbuf,smb_tid,cnum);
2587 p = smb_buf(outbuf);
2591 send_smb(Client,outbuf);
2592 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2594 if (CVAL(inbuf,smb_rcls) != 0)
2596 DEBUG(0,("%s removing remote directory file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
2602 /****************************************************************************
2604 ****************************************************************************/
2605 static void cmd_rename(char *inbuf,char *outbuf )
2611 strcpy(src,cur_dir);
2612 strcpy(dest,cur_dir);
2614 if (!next_token(NULL,buf,NULL) || !next_token(NULL,buf2,NULL))
2616 DEBUG(0,("rename <src> <dest>\n"));
2622 bzero(outbuf,smb_size);
2623 set_message(outbuf,1,4 + strlen(src) + strlen(dest),True);
2625 CVAL(outbuf,smb_com) = SMBmv;
2626 SSVAL(outbuf,smb_tid,cnum);
2627 SSVAL(outbuf,smb_vwv0,aHIDDEN | aDIR | aSYSTEM);
2630 p = smb_buf(outbuf);
2633 p = skip_string(p,1);
2637 send_smb(Client,outbuf);
2638 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2640 if (CVAL(inbuf,smb_rcls) != 0)
2642 DEBUG(0,("%s renaming files\n",smb_errstr(inbuf)));
2649 /****************************************************************************
2650 toggle the prompt flag
2651 ****************************************************************************/
2652 static void cmd_prompt(void)
2655 DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
2659 /****************************************************************************
2660 set the newer than time
2661 ****************************************************************************/
2662 static void cmd_newer(void)
2668 ok = next_token(NULL,buf,NULL);
2669 if (ok && (sys_stat(buf,&sbuf) == 0))
2671 newer_than = sbuf.st_mtime;
2672 DEBUG(1,("Getting files newer than %s",
2673 asctime(LocalTime(&newer_than,GMT_TO_LOCAL))));
2678 if (ok && newer_than == 0)
2679 DEBUG(0,("Error setting newer-than time\n"));
2682 /****************************************************************************
2683 set the archive level
2684 ****************************************************************************/
2685 static void cmd_archive(void)
2689 if (next_token(NULL,buf,NULL)) {
2690 archive_level = atoi(buf);
2692 DEBUG(0,("Archive level is %d\n",archive_level));
2695 /****************************************************************************
2696 toggle the lowercaseflag
2697 ****************************************************************************/
2698 static void cmd_lowercase(void)
2700 lowercase = !lowercase;
2701 DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
2707 /****************************************************************************
2708 toggle the recurse flag
2709 ****************************************************************************/
2710 static void cmd_recurse(void)
2713 DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
2716 /****************************************************************************
2717 toggle the translate flag
2718 ****************************************************************************/
2719 static void cmd_translate(void)
2721 translation = !translation;
2722 DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
2723 translation?"on":"off"));
2727 /****************************************************************************
2728 do a printmode command
2729 ****************************************************************************/
2730 static void cmd_printmode(void)
2735 if (next_token(NULL,buf,NULL))
2737 if (strequal(buf,"text"))
2741 if (strequal(buf,"graphics"))
2744 printmode = atoi(buf);
2751 strcpy(mode,"text");
2754 strcpy(mode,"graphics");
2757 sprintf(mode,"%d",printmode);
2761 DEBUG(2,("the printmode is now %s\n",mode));
2764 /****************************************************************************
2766 ****************************************************************************/
2767 static void cmd_lcd(void)
2772 if (next_token(NULL,buf,NULL))
2774 DEBUG(2,("the local directory is now %s\n",GetWd(d)));
2778 /****************************************************************************
2779 send a session request
2780 ****************************************************************************/
2781 static BOOL send_session_request(char *inbuf,char *outbuf)
2786 /* send a session request (RFC 8002) */
2788 strcpy(dest,desthost);
2789 p = strchr(dest,'.');
2792 /* put in the destination name */
2794 name_mangle(dest,p,name_type);
2799 name_mangle(myname,p,0);
2802 /* setup the packet length */
2803 _smb_setlen(outbuf,len);
2804 CVAL(outbuf,0) = 0x81;
2806 send_smb(Client,outbuf);
2807 DEBUG(5,("Sent session request\n"));
2809 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2811 if (CVAL(inbuf,0) == 0x84) /* C. Hoch 9/14/95 Start */
2813 /* For information, here is the response structure.
2814 * We do the byte-twiddling to for portability.
2815 struct RetargetResponse{
2817 unsigned char flags;
2824 int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
2825 /* SESSION RETARGET */
2826 putip((char *)&dest_ip,inbuf+4);
2829 Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
2833 DEBUG(3,("Retargeted\n"));
2835 set_socket_options(Client,user_socket_options);
2838 return send_session_request(inbuf,outbuf);
2839 } /* C. Hoch 9/14/95 End */
2842 if (CVAL(inbuf,0) != 0x82)
2844 int ecode = CVAL(inbuf,4);
2845 DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
2846 CVAL(inbuf,0),ecode,myname,desthost));
2850 DEBUG(0,("Not listening on called name\n"));
2851 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
2852 DEBUG(0,("You may find the -I option useful for this\n"));
2855 DEBUG(0,("Not listening for calling name\n"));
2856 DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
2857 DEBUG(0,("You may find the -n option useful for this\n"));
2860 DEBUG(0,("Called name not present\n"));
2861 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
2862 DEBUG(0,("You may find the -I option useful for this\n"));
2865 DEBUG(0,("Called name present, but insufficient resources\n"));
2866 DEBUG(0,("Perhaps you should try again later?\n"));
2869 DEBUG(0,("Unspecified error 0x%X\n",ecode));
2870 DEBUG(0,("Your server software is being unfriendly\n"));
2879 /****************************************************************************
2880 send a login command
2881 ****************************************************************************/
2882 static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
2884 BOOL was_null = (!inbuf && !outbuf);
2886 time_t servertime = 0;
2887 extern int serverzone;
2897 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
2898 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
2899 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
2900 {PROTOCOL_LANMAN1,"LANMAN1.0"},
2901 {PROTOCOL_LANMAN2,"LM1.2X002"},
2902 {PROTOCOL_LANMAN2,"Samba"},
2903 {PROTOCOL_NT1,"NT LM 0.12"},
2904 {PROTOCOL_NT1,"NT LANMAN 1.0"},
2914 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2915 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2919 if (strstr(service,"IPC$")) connect_as_ipc = True;
2923 if (connect_as_printer)
2924 strcpy(dev,"LPT1:");
2929 if (start_session && !send_session_request(inbuf,outbuf))
2939 bzero(outbuf,smb_size);
2941 /* setup the protocol strings */
2945 for (plength=0,numprots=0;
2946 prots[numprots].name && prots[numprots].prot<=max_protocol;
2948 plength += strlen(prots[numprots].name)+2;
2950 set_message(outbuf,0,plength,True);
2952 p = smb_buf(outbuf);
2954 prots[numprots].name && prots[numprots].prot<=max_protocol;
2958 strcpy(p,prots[numprots].name);
2963 CVAL(outbuf,smb_com) = SMBnegprot;
2966 CVAL(smb_buf(outbuf),0) = 2;
2968 send_smb(Client,outbuf);
2969 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2973 if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
2975 DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
2976 myname,desthost,smb_errstr(inbuf)));
2985 Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
2988 if (Protocol < PROTOCOL_NT1) {
2989 sec_mode = SVAL(inbuf,smb_vwv1);
2990 max_xmit = SVAL(inbuf,smb_vwv2);
2991 sesskey = IVAL(inbuf,smb_vwv6);
2992 serverzone = SVALS(inbuf,smb_vwv10)*60;
2993 /* this time is converted to GMT by make_unix_date */
2994 servertime = make_unix_date(inbuf+smb_vwv8);
2995 if (Protocol >= PROTOCOL_COREPLUS) {
2996 readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
2997 writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
2999 crypt_len = smb_buflen(inbuf);
3000 memcpy(cryptkey,smb_buf(inbuf),8);
3001 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
3002 max_vcs = SVAL(inbuf,smb_vwv4);
3003 DEBUG(3,("max vcs %d\n",max_vcs));
3004 DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
3007 sec_mode = CVAL(inbuf,smb_vwv1);
3008 max_xmit = IVAL(inbuf,smb_vwv3+1);
3009 sesskey = IVAL(inbuf,smb_vwv7+1);
3010 serverzone = SVALS(inbuf,smb_vwv15+1)*60;
3011 /* this time arrives in real GMT */
3012 servertime = interpret_long_date(inbuf+smb_vwv11+1);
3013 crypt_len = CVAL(inbuf,smb_vwv16+1);
3014 memcpy(cryptkey,smb_buf(inbuf),8);
3015 if (IVAL(inbuf,smb_vwv9+1) & 1)
3016 readbraw_supported = writebraw_supported = True;
3017 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
3018 max_vcs = SVAL(inbuf,smb_vwv2+1);
3019 DEBUG(3,("max vcs %d\n",max_vcs));
3020 DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
3021 DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
3024 DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
3025 DEBUG(3,("max xmt %d\n",max_xmit));
3026 DEBUG(3,("Got %d byte crypt key\n",crypt_len));
3027 DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
3029 doencrypt = ((sec_mode & 2) != 0);
3032 static BOOL done_time = False;
3034 DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
3035 asctime(LocalTime(&servertime,GMT_TO_LOCAL)),
3036 -(double)(serverzone/3600.0)));
3046 pass = (char *)getpass("Password: ");
3048 if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
3051 int passlen = strlen(pass)+1;
3055 if (doencrypt && *pass) {
3056 DEBUG(3,("Using encrypted passwords\n"));
3058 SMBencrypt(pass,cryptkey,pword);
3064 /* if in share level security then don't send a password now */
3065 if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;}
3067 /* send a session setup command */
3068 bzero(outbuf,smb_size);
3070 if (Protocol < PROTOCOL_NT1) {
3071 set_message(outbuf,10,1 + strlen(username) + passlen,True);
3072 CVAL(outbuf,smb_com) = SMBsesssetupX;
3075 CVAL(outbuf,smb_vwv0) = 0xFF;
3076 SSVAL(outbuf,smb_vwv2,max_xmit);
3077 SSVAL(outbuf,smb_vwv3,2);
3078 SSVAL(outbuf,smb_vwv4,max_vcs-1);
3079 SIVAL(outbuf,smb_vwv5,sesskey);
3080 SSVAL(outbuf,smb_vwv7,passlen);
3081 p = smb_buf(outbuf);
3082 memcpy(p,pword,passlen);
3086 if (!doencrypt) passlen--;
3088 set_message(outbuf,13,0,True);
3089 CVAL(outbuf,smb_com) = SMBsesssetupX;
3092 CVAL(outbuf,smb_vwv0) = 0xFF;
3093 SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
3094 SSVAL(outbuf,smb_vwv3,2);
3095 SSVAL(outbuf,smb_vwv4,getpid());
3096 SIVAL(outbuf,smb_vwv5,sesskey);
3097 SSVAL(outbuf,smb_vwv7,passlen);
3098 SSVAL(outbuf,smb_vwv8,0);
3099 p = smb_buf(outbuf);
3100 memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
3101 strcpy(p,username);p = skip_string(p,1);
3102 strcpy(p,workgroup);p = skip_string(p,1);
3103 strcpy(p,"Unix");p = skip_string(p,1);
3104 strcpy(p,"Samba");p = skip_string(p,1);
3105 set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
3108 send_smb(Client,outbuf);
3109 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
3113 if (CVAL(inbuf,smb_rcls) != 0)
3116 ((CVAL(inbuf,smb_rcls) == ERRDOS &&
3117 SVAL(inbuf,smb_err) == ERRnoaccess) ||
3118 (CVAL(inbuf,smb_rcls) == ERRSRV &&
3119 SVAL(inbuf,smb_err) == ERRbadpw)))
3122 DEBUG(3,("resending login\n"));
3126 DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
3127 username,myname,desthost,smb_errstr(inbuf)));
3128 DEBUG(0,("You might find the -U, -W or -n options useful\n"));
3129 DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
3130 DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
3139 if (Protocol >= PROTOCOL_NT1) {
3140 char *domain,*os,*lanman;
3143 lanman = skip_string(os,1);
3144 domain = skip_string(lanman,1);
3145 if (*domain || *os || *lanman)
3146 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
3149 /* use the returned uid from now on */
3150 if (SVAL(inbuf,smb_uid) != uid)
3151 DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
3152 SVAL(inbuf,smb_uid),uid));
3153 uid = SVAL(inbuf,smb_uid);
3156 /* now we've got a connection - send a tcon message */
3157 bzero(outbuf,smb_size);
3159 if (strncmp(service,"\\\\",2) != 0)
3161 DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
3162 DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
3169 int passlen = strlen(pass)+1;
3174 if (doencrypt && *pass) {
3176 SMBencrypt(pass,cryptkey,pword);
3180 /* if in user level security then don't send a password now */
3181 if ((sec_mode & 1)) {
3182 strcpy(pword, ""); passlen=1;
3185 set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
3186 CVAL(outbuf,smb_com) = SMBtconX;
3189 SSVAL(outbuf,smb_vwv0,0xFF);
3190 SSVAL(outbuf,smb_vwv3,passlen);
3192 p = smb_buf(outbuf);
3193 memcpy(p,pword,passlen);
3196 p = skip_string(p,1);
3200 send_smb(Client,outbuf);
3201 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
3203 /* trying again with a blank password */
3204 if (CVAL(inbuf,smb_rcls) != 0 &&
3205 (int)strlen(pass) > 0 &&
3207 Protocol >= PROTOCOL_LANMAN1)
3209 DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
3214 if (CVAL(inbuf,smb_rcls) != 0)
3216 DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
3217 DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
3218 DEBUG(0,("Some servers insist that these be in uppercase\n"));
3228 max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
3230 max_xmit = BUFFER_SIZE - 4;
3232 cnum = SVAL(inbuf,smb_tid);
3234 DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
3245 /****************************************************************************
3246 send a logout command
3247 ****************************************************************************/
3248 static void send_logout(void )
3250 pstring inbuf,outbuf;
3252 bzero(outbuf,smb_size);
3253 set_message(outbuf,0,0,True);
3254 CVAL(outbuf,smb_com) = SMBtdis;
3255 SSVAL(outbuf,smb_tid,cnum);
3258 send_smb(Client,outbuf);
3259 receive_smb(Client,inbuf,SHORT_TIMEOUT);
3261 if (CVAL(inbuf,smb_rcls) != 0)
3263 DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
3275 /****************************************************************************
3277 ****************************************************************************/
3278 static BOOL call_api(int prcnt,int drcnt,
3279 int mprcnt,int mdrcnt,
3280 int *rprcnt,int *rdrcnt,
3281 char *param,char *data,
3282 char **rparam,char **rdata)
3284 static char *inbuf=NULL;
3285 static char *outbuf=NULL;
3287 if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3288 if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3290 send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0,
3295 return (receive_trans_response(inbuf,SMBtrans,
3300 /****************************************************************************
3301 send a SMB trans or trans2 request
3302 ****************************************************************************/
3303 static BOOL send_trans_request(char *outbuf,int trans,
3304 char *name,int fid,int flags,
3305 char *data,char *param,uint16 *setup,
3306 int ldata,int lparam,int lsetup,
3307 int mdata,int mparam,int msetup)
3310 int this_ldata,this_lparam;
3311 int tot_data=0,tot_param=0;
3312 char *outdata,*outparam;
3316 this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
3317 this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
3319 bzero(outbuf,smb_size);
3320 set_message(outbuf,14+lsetup,0,True);
3321 CVAL(outbuf,smb_com) = trans;
3322 SSVAL(outbuf,smb_tid,cnum);
3325 outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
3326 outdata = outparam+this_lparam;
3328 /* primary request */
3329 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
3330 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
3331 SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
3332 SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
3333 SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
3334 SSVAL(outbuf,smb_flags,flags); /* flags */
3335 SIVAL(outbuf,smb_timeout,0); /* timeout */
3336 SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
3337 SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
3338 SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
3339 SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
3340 SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
3341 for (i=0;i<lsetup;i++) /* setup[] */
3342 SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
3343 p = smb_buf(outbuf);
3344 if (trans==SMBtrans)
3345 strcpy(p,name); /* name[] */
3348 *p++ = 0; /* put in a null smb_name */
3349 *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
3351 if (this_lparam) /* param[] */
3352 memcpy(outparam,param,this_lparam);
3353 if (this_ldata) /* data[] */
3354 memcpy(outdata,data,this_ldata);
3355 set_message(outbuf,14+lsetup, /* wcnt, bcc */
3356 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
3359 send_smb(Client,outbuf);
3361 if (this_ldata < ldata || this_lparam < lparam)
3363 /* receive interim response */
3364 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
3366 DEBUG(0,("%s request failed (%s)\n",
3367 trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
3371 tot_data = this_ldata;
3372 tot_param = this_lparam;
3374 while (tot_data < ldata || tot_param < lparam)
3376 this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
3377 this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
3379 set_message(outbuf,trans==SMBtrans?8:9,0,True);
3380 CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
3382 outparam = smb_buf(outbuf);
3383 outdata = outparam+this_lparam;
3385 /* secondary request */
3386 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
3387 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
3388 SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
3389 SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
3390 SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
3391 SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
3392 SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
3393 SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
3394 if (trans==SMBtrans2)
3395 SSVAL(outbuf,smb_sfid,fid); /* fid */
3396 if (this_lparam) /* param[] */
3397 memcpy(outparam,param,this_lparam);
3398 if (this_ldata) /* data[] */
3399 memcpy(outdata,data,this_ldata);
3400 set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
3401 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
3404 send_smb(Client,outbuf);
3406 tot_data += this_ldata;
3407 tot_param += this_lparam;
3414 /****************************************************************************
3415 try and browse available connections on a host
3416 ****************************************************************************/
3417 static BOOL browse_host(BOOL sort)
3420 #define strcasecmp StrCaseCmp
3422 extern int strcasecmp();
3424 char *rparam = NULL;
3431 /* now send a SMBtrans command with api RNetShareEnum */
3433 SSVAL(p,0,0); /* api number */
3436 p = skip_string(p,1);
3438 p = skip_string(p,1);
3440 SSVAL(p,2,BUFFER_SIZE);
3443 if (call_api(PTR_DIFF(p,param),0,
3449 int res = SVAL(rparam,0);
3450 int converter=SVAL(rparam,2);
3452 BOOL long_share_name=False;
3456 count=SVAL(rparam,4);
3461 printf("\n\tSharename Type Comment\n");
3462 printf("\t--------- ---- -------\n");
3466 qsort(p,count,20,QSORT_CAST strcasecmp);
3468 for (i=0;i<count;i++)
3471 int type = SVAL(p,14);
3472 int comment_offset = IVAL(p,16) & 0xFFFF;
3478 case STYPE_DISKTREE:
3479 strcpy(typestr,"Disk"); break;
3481 strcpy(typestr,"Printer"); break;
3483 strcpy(typestr,"Device"); break;
3485 strcpy(typestr,"IPC"); break;
3488 printf("\t%-15.15s%-10.10s%s\n",
3491 comment_offset?rdata+comment_offset-converter:"");
3493 if (strlen(sname)>8) long_share_name=True;
3498 if (long_share_name) {
3499 printf("\nNOTE: There were share names longer than 8 chars.\nOn older clients these may not be accessible or may give browsing errors\n");
3504 if (rparam) free(rparam);
3505 if (rdata) free(rdata);
3511 /****************************************************************************
3512 get some server info
3513 ****************************************************************************/
3514 static void server_info()
3516 char *rparam = NULL;
3522 bzero(param,sizeof(param));
3525 SSVAL(p,0,63); /* api number */
3528 p = skip_string(p,1);
3529 strcpy(p,"zzzBBzz");
3530 p = skip_string(p,1);
3531 SSVAL(p,0,10); /* level 10 */
3535 if (call_api(PTR_DIFF(p,param),0,
3541 int res = SVAL(rparam,0);
3542 int converter=SVAL(rparam,2);
3548 printf("\nServer=[%s] User=[%s] Workgroup=[%s] Domain=[%s]\n",
3549 rdata+SVAL(p,0)-converter,
3550 rdata+SVAL(p,4)-converter,
3551 rdata+SVAL(p,8)-converter,
3552 rdata+SVAL(p,14)-converter);
3556 if (rparam) free(rparam);
3557 if (rdata) free(rdata);
3563 /****************************************************************************
3564 try and browse available connections on a host
3565 ****************************************************************************/
3566 static BOOL list_servers()
3568 char *rparam = NULL;
3576 /* now send a SMBtrans command with api ServerEnum? */
3578 SSVAL(p,0,0x68); /* api number */
3580 strcpy(p,"WrLehDO");
3581 p = skip_string(p,1);
3583 strcpy(p,"B16BBDz");
3585 strcpy(p,getenv("XX_STR2"));
3588 p = skip_string(p,1);
3590 SSVAL(p,2,0x2000); /* buf length */
3593 SIVAL(p,0,SV_TYPE_ALL);
3595 if (call_api(PTR_DIFF(p+4,param),0,
3601 int res = SVAL(rparam,0);
3602 int converter=SVAL(rparam,2);
3607 count=SVAL(rparam,4);
3610 printf("\n\nThis machine has a browse list:\n");
3611 printf("\n\tServer Comment\n");
3612 printf("\t--------- -------\n");
3615 for (i=0;i<count;i++) {
3617 int comment_offset = IVAL(p2,22) & 0xFFFF;
3618 printf("\t%-16.16s %s\n",
3620 comment_offset?rdata+comment_offset-converter:"");
3627 if (rparam) {free(rparam); rparam = NULL;}
3628 if (rdata) {free(rdata); rdata = NULL;}
3630 SIVAL(p,0,SV_TYPE_DOMAIN_ENUM);
3632 if (call_api(PTR_DIFF(p+4,param),0,
3638 int res = SVAL(rparam,0);
3639 int converter=SVAL(rparam,2);
3644 count=SVAL(rparam,4);
3647 printf("\n\nThis machine has a workgroup list:\n");
3648 printf("\n\tWorkgroup Master\n");
3649 printf("\t--------- -------\n");
3652 for (i=0;i<count;i++) {
3654 int comment_offset = IVAL(p2,22) & 0xFFFF;
3655 printf("\t%-16.16s %s\n",
3657 comment_offset?rdata+comment_offset-converter:"");
3664 if (rparam) free(rparam);
3665 if (rdata) free(rdata);
3675 /* This defines the commands supported by this client */
3683 {"ls",cmd_dir,"<mask> list the contents of the current directory"},
3684 {"dir",cmd_dir,"<mask> list the contents of the current directory"},
3685 {"lcd",cmd_lcd,"[directory] change/report the local current working directory"},
3686 {"cd",cmd_cd,"[directory] change/report the remote directory"},
3687 {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)"},
3688 {"get",cmd_get,"<remote name> [local name] get a file"},
3689 {"mget",cmd_mget,"<mask> get all the matching files"},
3690 {"put",cmd_put,"<local name> [remote name] put a file"},
3691 {"mput",cmd_mput,"<mask> put all matching files"},
3692 {"rename",cmd_rename,"<src> <dest> rename some files"},
3693 {"more",cmd_more,"<remote name> view a remote file with your pager"},
3694 {"mask",cmd_select,"<mask> mask all filenames against this"},
3695 {"del",cmd_del,"<mask> delete all matching files"},
3696 {"rm",cmd_del,"<mask> delete all matching files"},
3697 {"mkdir",cmd_mkdir,"<directory> make a directory"},
3698 {"md",cmd_mkdir,"<directory> make a directory"},
3699 {"rmdir",cmd_rmdir,"<directory> remove a directory"},
3700 {"rd",cmd_rmdir,"<directory> remove a directory"},
3701 {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput"},
3702 {"recurse",cmd_recurse,"toggle directory recursion for mget and mput"},
3703 {"translate",cmd_translate,"toggle text translation for printing"},
3704 {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get"},
3705 {"print",cmd_print,"<file name> print a file"},
3706 {"printmode",cmd_printmode,"<graphics or text> set the print mode"},
3707 {"queue",cmd_queue,"show the print queue"},
3708 {"cancel",cmd_cancel,"<jobid> cancel a print queue entry"},
3709 {"stat",cmd_stat,"<file> get info on a file (experimental!)"},
3710 {"quit",send_logout,"logoff the server"},
3711 {"q",send_logout,"logoff the server"},
3712 {"exit",send_logout,"logoff the server"},
3713 {"newer",cmd_newer,"<file> only mget files newer than the specified local file"},
3714 {"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"},
3715 {"tar",cmd_tar,"tar <c|x>[IXbgNa] current directory to/from <file name>" },
3716 {"blocksize",cmd_block,"blocksize <number> (default 20)" },
3717 {"tarmode",cmd_tarmode,
3718 "<full|inc|reset|noreset> tar's behaviour towards archive bits" },
3719 {"setmode",cmd_setmode,"filename <setmode string> change modes of file"},
3720 {"help",cmd_help,"[command] give help on a command"},
3721 {"?",cmd_help,"[command] give help on a command"},
3722 {"!",NULL,"run a shell command on the local system"},
3727 /*******************************************************************
3728 lookup a command string in the list of commands, including
3730 ******************************************************************/
3731 static int process_tok(fstring tok)
3733 int i = 0, matches = 0;
3735 int tok_len = strlen(tok);
3737 while (commands[i].fn != NULL)
3739 if (strequal(commands[i].name,tok))
3745 else if (strnequal(commands[i].name, tok, tok_len+1))
3755 else if (matches == 1)
3761 /****************************************************************************
3763 ****************************************************************************/
3769 if (next_token(NULL,buf,NULL))
3771 if ((i = process_tok(buf)) >= 0)
3772 DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));
3775 while (commands[i].description)
3777 for (j=0; commands[i].description && (j<5); j++) {
3778 DEBUG(0,("%-15s",commands[i].name));
3785 /****************************************************************************
3786 open the client sockets
3787 ****************************************************************************/
3788 static BOOL open_sockets(int port )
3790 static int last_port;
3798 if (port == 0) port=last_port;
3809 strcpy(service2,service);
3810 host = strtok(service2,"\\/");
3812 DEBUG(0,("Badly formed host name\n"));
3815 strcpy(desthost,host);
3818 DEBUG(3,("Opening sockets\n"));
3822 get_myname(myname,NULL);
3830 if ((hp = Get_Hostbyname(host))) {
3831 putip((char *)&dest_ip,(char *)hp->h_addr);
3835 /* Try and resolve the name with the netbios server */
3838 struct in_addr ip1, ip2;
3840 if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) {
3841 set_socket_options (bcast, "SO_BROADCAST");
3843 if (!got_bcast && get_myname(hs, &ip1)) {
3844 get_broadcast(&ip1, &bcast_ip, &ip2);
3847 if (name_query(bcast, host, 0x20, True, True, bcast_ip, &dest_ip,0)){
3854 DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
3860 Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
3864 DEBUG(3,("Connected\n"));
3866 set_socket_options(Client,user_socket_options);
3871 /****************************************************************************
3872 wait for keyboard activity, swallowing network packets
3873 ****************************************************************************/
3875 static char wait_keyboard(char *buffer)
3877 static void wait_keyboard(char *buffer)
3882 struct timeval timeout;
3892 FD_SET(Client,&fds);
3894 FD_SET(fileno(stdin),&fds);
3897 timeout.tv_sec = 20;
3898 timeout.tv_usec = 0;
3902 selrtn = sys_select(&fds,&timeout);
3905 if (FD_ISSET(fileno(stdin),&fds))
3913 f_flags = fcntl(fileno(stdin), F_GETFL, 0);
3914 fcntl( fileno(stdin), F_SETFL, f_flags | O_NONBLOCK);
3915 readret = read_data( fileno(stdin), &ch, 1);
3916 fcntl(fileno(stdin), F_SETFL, f_flags);
3919 if (errno != EAGAIN)
3921 /* should crash here */
3922 DEBUG(1,("readchar stdin failed\n"));
3925 else if (readret != 0)
3931 if (FD_ISSET(Client,&fds))
3932 receive_smb(Client,buffer,0);
3939 chkpath("\\",False);
3942 chkpath("\\",False);
3948 /****************************************************************************
3949 close and open the connection again
3950 ****************************************************************************/
3951 BOOL reopen_connection(char *inbuf,char *outbuf)
3953 static int open_count=0;
3957 if (open_count>5) return(False);
3959 DEBUG(1,("Trying to re-open connection\n"));
3961 set_message(outbuf,0,0,True);
3962 SCVAL(outbuf,smb_com,SMBtdis);
3963 SSVAL(outbuf,smb_tid,cnum);
3966 send_smb(Client,outbuf);
3967 receive_smb(Client,inbuf,SHORT_TIMEOUT);
3970 if (!open_sockets(0)) return(False);
3972 return(send_login(inbuf,outbuf,True,True));
3975 /****************************************************************************
3976 process commands from the client
3977 ****************************************************************************/
3978 BOOL process(char *base_directory)
3983 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3984 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3986 if ((InBuffer == NULL) || (OutBuffer == NULL))
3989 bzero(OutBuffer,smb_size);
3991 if (!send_login(InBuffer,OutBuffer,True,True))
3994 if (*base_directory) do_cd(base_directory);
3996 while (!feof(stdin))
4001 bzero(OutBuffer,smb_size);
4003 /* display a prompt */
4004 DEBUG(1,("smb: %s> ", CNV_LANG(cur_dir)));
4008 line[0] = wait_keyboard(InBuffer);
4009 /* this might not be such a good idea... */
4010 if ( line[0] == EOF)
4013 wait_keyboard(InBuffer);
4016 /* and get a response */
4018 fgets( &line[1],999, stdin);
4020 if (!fgets(line,1000,stdin))
4024 /* input language code to internal one */
4027 /* special case - first char is ! */
4034 /* and get the first part of the command */
4037 if (!next_token(&ptr,tok,NULL)) continue;
4040 if ((i = process_tok(tok)) >= 0)
4041 commands[i].fn(InBuffer,OutBuffer);
4043 DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
4045 DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
4053 /****************************************************************************
4054 usage on the program
4055 ****************************************************************************/
4056 void usage(char *pname)
4058 DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
4062 DEBUG(0,("[-t termcode] "));
4065 DEBUG(0,("\nVersion %s\n",VERSION));
4066 DEBUG(0,("\t-p port listen on the specified port\n"));
4067 DEBUG(0,("\t-d debuglevel set the debuglevel\n"));
4068 DEBUG(0,("\t-l log basename. Basename for log/debug files\n"));
4069 DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n"));
4070 DEBUG(0,("\t-N don't ask for a password\n"));
4071 DEBUG(0,("\t-P connect to service as a printer\n"));
4072 DEBUG(0,("\t-M host send a winpopup message to the host\n"));
4073 DEBUG(0,("\t-m max protocol set the max protocol level\n"));
4074 DEBUG(0,("\t-L host get a list of shares available on a host\n"));
4075 DEBUG(0,("\t-I dest IP use this IP to connect to\n"));
4076 DEBUG(0,("\t-E write messages to stderr instead of stdout\n"));
4077 DEBUG(0,("\t-U username set the network username\n"));
4078 DEBUG(0,("\t-W workgroup set the workgroup name\n"));
4080 DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
4082 DEBUG(0,("\t-T<c|x>IXgbNa command line tar\n"));
4083 DEBUG(0,("\t-D directory start from directory\n"));
4089 /****************************************************************************
4091 ****************************************************************************/
4092 int main(int argc,char *argv[])
4094 fstring base_directory;
4095 char *pname = argv[0];
4099 extern char *optarg;
4102 BOOL message = False;
4103 extern char tar_type;
4106 *base_directory = 0;
4110 setup_logging(pname,True);
4113 charset_initialise();
4124 strcpy(username,getenv("USER"));
4128 if (*username == 0 && getenv("LOGNAME"))
4130 strcpy(username,getenv("LOGNAME"));
4140 if (*argv[1] != '-')
4143 strcpy(service,argv[1]);
4147 if (count_chars(service,'\\') < 3)
4150 printf("\n%s: Not enough '\\' characters in service\n",service);
4155 if (count_chars(service,'\\') > 3)
4158 printf("\n%s: Too many '\\' characters in service\n",service);
4163 if (argc > 1 && (*argv[1] != '-'))
4166 strcpy(password,argv[1]);
4167 memset(argv[1],'X',strlen(argv[1]));
4174 setup_term_code (KANJI);
4175 while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:")) != EOF)
4177 while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:m:W:T:D:")) != EOF)
4182 max_protocol = interpret_protocol(optarg,max_protocol);
4185 strcpy(user_socket_options,optarg);
4189 strcpy(desthost,optarg);
4194 bcast_ip = *interpret_addr2(optarg);
4198 strcpy(base_directory,optarg);
4201 if (!tar_parseargs(argc, argv, optarg, optind)) {
4207 strcpy(scope,optarg);
4211 strcpy(query_host,optarg);
4216 strcpy(username,optarg);
4217 if ((p=strchr(username,'%')))
4220 strcpy(password,p+1);
4222 memset(strchr(optarg,'%')+1,'X',strlen(password));
4228 strcpy(workgroup,optarg);
4235 dest_ip = *interpret_addr2(optarg);
4236 if (zero_ip(dest_ip)) exit(1);
4241 strcpy(myname,optarg);
4247 connect_as_printer = True;
4253 DEBUGLEVEL = atoi(optarg);
4256 sprintf(debugf,"%s.client",optarg);
4259 port = atoi(optarg);
4267 if (!setup_term_code (optarg)) {
4268 DEBUG(0, ("%s: unknown terminal code name\n", optarg));
4279 if (!tar_type && !*query_host && !*service && !message)
4286 DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
4288 get_myname(*myname?NULL:myname,&myip);
4294 if (open_sockets(port)) {
4295 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4296 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4299 if ((InBuffer == NULL) || (OutBuffer == NULL))
4302 bzero(OutBuffer,smb_size);
4303 if (!send_login(InBuffer,OutBuffer,True,True))
4306 if (*base_directory) do_cd(base_directory);
4308 ret=process_tar(InBuffer, OutBuffer);
4320 sprintf(service,"\\\\%s\\IPC$",query_host);
4322 connect_as_ipc = True;
4323 if (open_sockets(port))
4328 if (!send_login(NULL,NULL,True,True))
4332 if (!browse_host(True)) {
4336 if (!list_servers()) {
4351 if (open_sockets(port))
4353 pstring inbuf,outbuf;
4354 bzero(outbuf,smb_size);
4355 if (!send_session_request(inbuf,outbuf))
4358 send_message(inbuf,outbuf);
4366 if (open_sockets(port))
4368 if (!process(base_directory))
4382 /* error code stuff - put together by Merik Karman
4383 merik@blackadder.dsh.oz.au */
4392 /* Dos Error Messages */
4393 err_code_struct dos_msgs[] = {
4394 {"ERRbadfunc",1,"Invalid function."},
4395 {"ERRbadfile",2,"File not found."},
4396 {"ERRbadpath",3,"Directory invalid."},
4397 {"ERRnofids",4,"No file descriptors available"},
4398 {"ERRnoaccess",5,"Access denied."},
4399 {"ERRbadfid",6,"Invalid file handle."},
4400 {"ERRbadmcb",7,"Memory control blocks destroyed."},
4401 {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
4402 {"ERRbadmem",9,"Invalid memory block address."},
4403 {"ERRbadenv",10,"Invalid environment."},
4404 {"ERRbadformat",11,"Invalid format."},
4405 {"ERRbadaccess",12,"Invalid open mode."},
4406 {"ERRbaddata",13,"Invalid data."},
4407 {"ERR",14,"reserved."},
4408 {"ERRbaddrive",15,"Invalid drive specified."},
4409 {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
4410 {"ERRdiffdevice",17,"Not same device."},
4411 {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
4412 {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
4413 {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
4414 {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
4415 {"ERRbadpipe",230,"Pipe invalid."},
4416 {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
4417 {"ERRpipeclosing",232,"Pipe close in progress."},
4418 {"ERRnotconnected",233,"No process on other end of pipe."},
4419 {"ERRmoredata",234,"There is more data to be returned."},
4420 {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
4423 /* Server Error Messages */
4424 err_code_struct server_msgs[] = {
4425 {"ERRerror",1,"Non-specific error code."},
4426 {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
4427 {"ERRbadtype",3,"reserved."},
4428 {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."},
4429 {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
4430 {"ERRinvnetname",6,"Invalid network name in tree connect."},
4431 {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."},
4432 {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
4433 {"ERRqtoobig",50,"Print queue full -- no space."},
4434 {"ERRqeof",51,"EOF on print queue dump."},
4435 {"ERRinvpfid",52,"Invalid print file FID."},
4436 {"ERRsmbcmd",64,"The server did not recognize the command received."},
4437 {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
4438 {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."},
4439 {"ERRreserved",68,"reserved."},
4440 {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."},
4441 {"ERRreserved",70,"reserved."},
4442 {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
4443 {"ERRpaused",81,"Server is paused."},
4444 {"ERRmsgoff",82,"Not receiving messages."},
4445 {"ERRnoroom",83,"No room to buffer message."},
4446 {"ERRrmuns",87,"Too many remote user names."},
4447 {"ERRtimeout",88,"Operation timed out."},
4448 {"ERRnoresource",89,"No resources currently available for request."},
4449 {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
4450 {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
4451 {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
4452 {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
4453 {"ERRcontmpx",252,"Continue in MPX mode."},
4454 {"ERRreserved",253,"reserved."},
4455 {"ERRreserved",254,"reserved."},
4456 {"ERRnosupport",0xFFFF,"Function not supported."},
4459 /* Hard Error Messages */
4460 err_code_struct hard_msgs[] = {
4461 {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
4462 {"ERRbadunit",20,"Unknown unit."},
4463 {"ERRnotready",21,"Drive not ready."},
4464 {"ERRbadcmd",22,"Unknown command."},
4465 {"ERRdata",23,"Data error (CRC)."},
4466 {"ERRbadreq",24,"Bad request structure length."},
4467 {"ERRseek",25 ,"Seek error."},
4468 {"ERRbadmedia",26,"Unknown media type."},
4469 {"ERRbadsector",27,"Sector not found."},
4470 {"ERRnopaper",28,"Printer out of paper."},
4471 {"ERRwrite",29,"Write fault."},
4472 {"ERRread",30,"Read fault."},
4473 {"ERRgeneral",31,"General failure."},
4474 {"ERRbadshare",32,"A open conflicts with an existing open."},
4475 {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
4476 {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
4477 {"ERRFCBUnavail",35,"No FCBs are available to process request."},
4478 {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
4486 err_code_struct *err_msgs;
4489 {0x01,"ERRDOS",dos_msgs},
4490 {0x02,"ERRSRV",server_msgs},
4491 {0x03,"ERRHRD",hard_msgs},
4492 {0x04,"ERRXOS",NULL},
4493 {0xE1,"ERRRMX1",NULL},
4494 {0xE2,"ERRRMX2",NULL},
4495 {0xE3,"ERRRMX3",NULL},
4496 {0xFF,"ERRCMD",NULL},
4500 /****************************************************************************
4501 return a SMB error string from a SMB buffer
4502 ****************************************************************************/
4503 char *smb_errstr(char *inbuf)
4506 int class = CVAL(inbuf,smb_rcls);
4507 int num = SVAL(inbuf,smb_err);
4510 for (i=0;err_classes[i].class;i++)
4511 if (err_classes[i].code == class)
4513 if (err_classes[i].err_msgs)
4515 err_code_struct *err = err_classes[i].err_msgs;
4516 for (j=0;err[j].name;j++)
4517 if (num == err[j].code)
4520 sprintf(ret,"%s - %s (%s)",err_classes[i].class,
4521 err[j].name,err[j].message);
4523 sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
4528 sprintf(ret,"%s - %d",err_classes[i].class,num);
4532 sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);