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.
32 pstring cur_dir = "\\";
37 pstring password = "";
39 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 ipzero;
49 extern pstring user_socket_options;
51 /* 30 second timeout on most commands */
52 #define CLIENT_TIMEOUT (30*1000)
53 #define SHORT_TIMEOUT (5*1000)
55 /* value for unused fid field in trans2 secondary request */
56 #define FID_UNUSED (0xFFFF)
60 int max_protocol = PROTOCOL_NT1;
63 time_t newer_than = 0;
64 int archive_level = 0;
66 extern pstring debugf;
67 extern int DEBUGLEVEL;
69 BOOL translation = False;
72 static BOOL send_trans_request(char *outbuf,int trans,
73 char *name,int fid,int flags,
74 char *data,char *param,uint16 *setup,
75 int ldata,int lparam,int lsetup,
76 int mdata,int mparam,int msetup);
77 static BOOL receive_trans_response(char *inbuf,int trans,
78 int *data_len,int *param_len,
79 char **data,char **param);
80 static int interpret_long_filename(int level,char *p,file_info *finfo);
81 static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir);
82 static int interpret_short_filename(char *p,file_info *finfo);
83 static BOOL call_api(int prcnt,int drcnt,
84 int mprcnt,int mdrcnt,
85 int *rprcnt,int *rdrcnt,
86 char *param,char *data,
87 char **rparam,char **rdata);
90 /* clitar bits insert */
93 extern BOOL tar_reset;
104 int max_xmit = BUFFER_SIZE;
106 extern pstring scope;
112 BOOL recurse = False;
113 BOOL lowercase = False;
115 BOOL have_ip = False;
117 struct in_addr dest_ip;
119 #define SEPARATORS " \t\n\r"
121 BOOL abort_mget = True;
125 BOOL readbraw_supported = False;
126 BOOL writebraw_supported = False;
128 pstring fileselection = "";
130 extern file_info def_finfo;
133 int get_total_size = 0;
134 int get_total_time_ms = 0;
135 int put_total_size = 0;
136 int put_total_time_ms = 0;
144 extern int coding_system;
145 #define CNV_LANG(s) (coding_system == DOSV_CODE?s:dos_to_unix(s, False))
146 #define CNV_INPUT(s) (coding_system == DOSV_CODE?s:unix_to_dos(s, True))
148 setup_term_code (char *code)
151 new = interpret_coding_system (code, UNKNOWN_CODE);
152 if (new != UNKNOWN_CODE) {
159 #define CNV_LANG(s) dos2unix_format(s,False)
160 #define CNV_INPUT(s) unix2dos_format(s,True)
163 /****************************************************************************
164 setup basics in a outgoing packet
165 ****************************************************************************/
166 void setup_pkt(char *outbuf)
168 SSVAL(outbuf,smb_pid,pid);
169 SSVAL(outbuf,smb_uid,uid);
170 SSVAL(outbuf,smb_mid,mid);
171 if (Protocol > PROTOCOL_CORE)
173 SCVAL(outbuf,smb_flg,0x8);
174 SSVAL(outbuf,smb_flg2,0x1);
178 /****************************************************************************
179 write to a local file with CR/LF->LF translation if appropriate. return the
180 number taken from the buffer. This may not equal the number written.
181 ****************************************************************************/
182 static int writefile(int f, char *b, int n)
187 return(write(f,b,n));
192 if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n')
196 if (write(f, b, 1) != 1)
207 /****************************************************************************
208 read from a file with LF->CR/LF translation if appropriate. return the
209 number read. read approx n bytes.
210 ****************************************************************************/
211 static int readfile(char *b, int size, int n, FILE *f)
216 if (!translation || (size != 1))
217 return(fread(b,size,n,f));
222 if ((c = getc(f)) == EOF)
227 if (c == '\n') /* change all LFs to CR/LF */
240 /****************************************************************************
241 read from a file with print translation. return the number read. read approx n
243 ****************************************************************************/
244 static int printread(FILE *f,char *b,int n)
248 i = readfile(b,1, n-1,f);
257 /****************************************************************************
258 check for existance of a dir
259 ****************************************************************************/
260 static BOOL chkpath(char *path,BOOL report)
263 pstring inbuf,outbuf;
267 trim_string(path2,NULL,"\\");
268 if (!*path2) *path2 = '\\';
270 bzero(outbuf,smb_size);
271 set_message(outbuf,0,4 + strlen(path2),True);
272 SCVAL(outbuf,smb_com,SMBchkpth);
273 SSVAL(outbuf,smb_tid,cnum);
280 send_smb(Client,outbuf);
281 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
283 if (report && CVAL(inbuf,smb_rcls) != 0)
284 DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
286 return(CVAL(inbuf,smb_rcls) == 0);
290 /****************************************************************************
292 ****************************************************************************/
293 static void send_message(char *inbuf,char *outbuf)
300 /* send a SMBsendstrt command */
301 bzero(outbuf,smb_size);
302 set_message(outbuf,0,0,True);
303 CVAL(outbuf,smb_com) = SMBsendstrt;
304 SSVAL(outbuf,smb_tid,cnum);
309 p = skip_string(p,1);
312 p = skip_string(p,1);
314 set_message(outbuf,0,PTR_DIFF(p,smb_buf(outbuf)),False);
316 send_smb(Client,outbuf);
319 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
321 printf("SMBsendstrt failed. (%s)\n",smb_errstr(inbuf));
325 grp_id = SVAL(inbuf,smb_vwv0);
327 printf("Connected. Type your message, ending it with a Control-D\n");
329 while (!feof(stdin) && total_len < 1600)
331 int maxlen = MIN(1600 - total_len,127);
338 for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++)
345 CVAL(outbuf,smb_com) = SMBsendtxt;
347 set_message(outbuf,1,l+3,True);
349 SSVAL(outbuf,smb_vwv0,grp_id);
356 send_smb(Client,outbuf);
359 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
361 printf("SMBsendtxt failed (%s)\n",smb_errstr(inbuf));
368 if (total_len >= 1600)
369 printf("the message was truncated to 1600 bytes ");
371 printf("sent %d bytes ",total_len);
373 printf("(status was %d-%d)\n",CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err));
375 CVAL(outbuf,smb_com) = SMBsendend;
376 set_message(outbuf,1,0,False);
377 SSVAL(outbuf,smb_vwv0,grp_id);
379 send_smb(Client,outbuf);
382 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
384 printf("SMBsendend failed (%s)\n",smb_errstr(inbuf));
391 /****************************************************************************
392 check the space on a device
393 ****************************************************************************/
394 static void do_dskattr(void)
396 pstring inbuf,outbuf;
398 bzero(outbuf,smb_size);
399 set_message(outbuf,0,0,True);
400 CVAL(outbuf,smb_com) = SMBdskattr;
401 SSVAL(outbuf,smb_tid,cnum);
404 send_smb(Client,outbuf);
405 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
407 if (CVAL(inbuf,smb_rcls) != 0)
408 DEBUG(0,("Error in dskattr: %s\n",smb_errstr(inbuf)));
410 DEBUG(0,("\n\t\t%d blocks of size %d. %d blocks available\n",
411 SVAL(inbuf,smb_vwv0),
412 SVAL(inbuf,smb_vwv1)*SVAL(inbuf,smb_vwv2),
413 SVAL(inbuf,smb_vwv3)));
416 /****************************************************************************
418 ****************************************************************************/
419 static void cmd_pwd(void)
421 DEBUG(0,("Current directory is %s",CNV_LANG(service)));
422 DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
426 /****************************************************************************
427 change directory - inner section
428 ****************************************************************************/
429 static void do_cd(char *newdir)
435 /* Save the current directory in case the
436 new directory is invalid */
437 strcpy(saved_dir, cur_dir);
442 if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
443 strcat(cur_dir, "\\");
445 dos_clean_name(cur_dir);
446 strcpy(dname,cur_dir);
447 strcat(cur_dir,"\\");
448 dos_clean_name(cur_dir);
450 if (!strequal(cur_dir,"\\"))
451 if (!chkpath(dname,True))
452 strcpy(cur_dir,saved_dir);
454 strcpy(cd_path,cur_dir);
457 /****************************************************************************
459 ****************************************************************************/
460 static void cmd_cd(char *inbuf,char *outbuf)
464 if (next_token(NULL,buf,NULL))
467 DEBUG(0,("Current directory is %s\n",CNV_LANG(cur_dir)));
471 /****************************************************************************
472 display info about a file
473 ****************************************************************************/
474 static void display_finfo(file_info *finfo)
476 time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
477 DEBUG(0,(" %-30s%7.7s%10d %s",
478 CNV_LANG(finfo->name),
479 attrib_string(finfo->mode),
481 asctime(LocalTime(&t))));
485 /****************************************************************************
486 do a directory listing, calling fn on each file found. Use the TRANSACT2
487 call for long filenames
488 ****************************************************************************/
489 static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
491 int max_matches = 512;
492 int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
497 char *dirlist = NULL;
499 int total_received = 0;
501 char *resp_data=NULL;
502 char *resp_param=NULL;
503 int resp_data_len = 0;
504 int resp_param_len=0;
506 int ff_resume_key = 0;
507 int ff_searchcount=0;
521 if (loop_count > 200)
523 DEBUG(0,("ERROR: Looping in FIND_NEXT??\n"));
529 setup = TRANSACT2_FINDFIRST;
530 SSVAL(param,0,attribute); /* attribute */
531 SSVAL(param,2,max_matches); /* max count */
532 SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
533 SSVAL(param,6,info_level);
535 strcpy(param+12,mask);
539 setup = TRANSACT2_FINDNEXT;
540 SSVAL(param,0,ff_dir_handle);
541 SSVAL(param,2,max_matches); /* max count */
542 SSVAL(param,4,info_level);
543 SIVAL(param,6,ff_resume_key); /* ff_resume_key */
544 SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
545 strcpy(param+12,mask);
547 DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
548 ff_dir_handle,ff_resume_key,ff_lastname,mask));
550 /* ??? original code added 1 pad byte after param */
552 send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
554 0,12+strlen(mask)+1,1,
557 if (!receive_trans_response(inbuf,SMBtrans2,
558 &resp_data_len,&resp_param_len,
559 &resp_data,&resp_param))
561 DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
565 /* parse out some important return info */
569 ff_dir_handle = SVAL(p,0);
570 ff_searchcount = SVAL(p,2);
572 ff_lastname = SVAL(p,8);
576 ff_searchcount = SVAL(p,0);
578 ff_lastname = SVAL(p,6);
581 if (ff_searchcount == 0)
584 /* point to the data bytes */
587 /* we might need the lastname for continuations */
594 StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
595 /* strcpy(mask,p+ff_lastname+94); */
598 strcpy(mask,p + ff_lastname + 1);
606 /* and add them to the dirlist pool */
607 dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
611 DEBUG(0,("Failed to expand dirlist\n"));
615 /* put in a length for the last entry, to ensure we can chain entries
616 into the next packet */
619 for (p2=p,i=0;i<(ff_searchcount-1);i++)
620 p2 += interpret_long_filename(info_level,p2,NULL);
621 SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
624 /* grab the data for later use */
625 memcpy(dirlist+dirlist_len,p,resp_data_len);
626 dirlist_len += resp_data_len;
628 total_received += ff_searchcount;
630 if (resp_data) free(resp_data); resp_data = NULL;
631 if (resp_param) free(resp_param); resp_param = NULL;
633 DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
634 ff_searchcount,ff_eos,ff_resume_key));
640 for (p=dirlist,i=0;i<total_received;i++)
642 p += interpret_long_filename(info_level,p,&finfo);
643 display_finfo(&finfo);
646 for (p=dirlist,i=0;i<total_received;i++)
648 p += interpret_long_filename(info_level,p,&finfo);
649 dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
652 /* free up the dirlist buffer */
653 if (dirlist) free(dirlist);
654 return(total_received);
658 /****************************************************************************
659 do a directory listing, calling fn on each file found
660 ****************************************************************************/
661 static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
667 int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
668 int num_received = 0;
670 char *dirlist = NULL;
682 bzero(outbuf,smb_size);
684 set_message(outbuf,2,5 + strlen(mask),True);
686 set_message(outbuf,2,5 + 21,True);
689 if (Protocol >= PROTOCOL_LANMAN1)
690 CVAL(outbuf,smb_com) = SMBffirst;
693 CVAL(outbuf,smb_com) = SMBsearch;
695 SSVAL(outbuf,smb_tid,cnum);
698 SSVAL(outbuf,smb_vwv0,num_asked);
699 SSVAL(outbuf,smb_vwv1,attribute);
720 send_smb(Client,outbuf);
721 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
723 received = SVAL(inbuf,smb_vwv0);
725 DEBUG(5,("dir received %d\n",received));
727 DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
729 if (received <= 0) break;
733 dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
738 p = smb_buf(inbuf) + 3;
740 memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
741 p,received*DIR_STRUCT_SIZE);
743 memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
745 num_received += received;
747 if (CVAL(inbuf,smb_rcls) != 0) break;
751 if (!first && Protocol >= PROTOCOL_LANMAN1)
753 bzero(outbuf,smb_size);
754 CVAL(outbuf,smb_com) = SMBfclose;
756 SSVAL(outbuf,smb_tid,cnum);
770 send_smb(Client,outbuf);
771 receive_smb(Client,inbuf,CLIENT_TIMEOUT,False);
773 if (CVAL(inbuf,smb_rcls) != 0)
774 DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));
779 for (p=dirlist,i=0;i<num_received;i++)
781 p += interpret_short_filename(p,&finfo);
782 display_finfo(&finfo);
785 for (p=dirlist,i=0;i<num_received;i++)
787 p += interpret_short_filename(p,&finfo);
788 dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
791 if (dirlist) free(dirlist);
792 return(num_received);
797 /****************************************************************************
798 do a directory listing, calling fn on each file found
799 ****************************************************************************/
800 void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
802 DEBUG(5,("do_dir(%s,%x,%s)\n",Mask,attribute,BOOLSTR(recurse_dir)));
803 if (Protocol >= PROTOCOL_LANMAN2)
805 if (do_long_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir) > 0)
809 expand_mask(Mask,False);
810 do_short_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir);
814 /*******************************************************************
815 decide if a file should be operated on
816 ********************************************************************/
817 static BOOL do_this_one(file_info *finfo)
819 if (finfo->mode & aDIR) return(True);
821 if (newer_than && finfo->mtime < newer_than)
824 if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH))
830 /****************************************************************************
831 interpret a short filename structure
832 The length of the structure is returned
833 ****************************************************************************/
834 static int interpret_short_filename(char *p,file_info *finfo)
836 finfo->mode = CVAL(p,21);
838 /* this date is converted to GMT by make_unix_date */
839 finfo->ctime = make_unix_date(p+22);
840 finfo->mtime = finfo->atime = finfo->ctime;
841 finfo->size = IVAL(p,26);
842 strcpy(finfo->name,p+30);
844 return(DIR_STRUCT_SIZE);
847 /****************************************************************************
848 interpret a long filename structure - this is mostly guesses at the moment
849 The length of the structure is returned
850 The structure of a long filename depends on the info level. 260 is used
851 by NT and 2 is used by OS/2
852 ****************************************************************************/
853 static int interpret_long_filename(int level,char *p,file_info *finfo)
856 memcpy(finfo,&def_finfo,sizeof(*finfo));
860 case 1: /* OS/2 understands this */
863 /* these dates are converted to GMT by make_unix_date */
864 finfo->ctime = make_unix_date2(p+4);
865 finfo->atime = make_unix_date2(p+8);
866 finfo->mtime = make_unix_date2(p+12);
867 finfo->size = IVAL(p,16);
868 finfo->mode = CVAL(p,24);
869 strcpy(finfo->name,p+27);
871 return(28 + CVAL(p,26));
873 case 2: /* this is what OS/2 uses mostly */
876 /* these dates are converted to GMT by make_unix_date */
877 finfo->ctime = make_unix_date2(p+4);
878 finfo->atime = make_unix_date2(p+8);
879 finfo->mtime = make_unix_date2(p+12);
880 finfo->size = IVAL(p,16);
881 finfo->mode = CVAL(p,24);
882 strcpy(finfo->name,p+31);
884 return(32 + CVAL(p,30));
886 /* levels 3 and 4 are untested */
890 /* these dates are probably like the other ones */
891 finfo->ctime = make_unix_date2(p+8);
892 finfo->atime = make_unix_date2(p+12);
893 finfo->mtime = make_unix_date2(p+16);
894 finfo->size = IVAL(p,20);
895 finfo->mode = CVAL(p,28);
896 strcpy(finfo->name,p+33);
903 /* these dates are probably like the other ones */
904 finfo->ctime = make_unix_date2(p+8);
905 finfo->atime = make_unix_date2(p+12);
906 finfo->mtime = make_unix_date2(p+16);
907 finfo->size = IVAL(p,20);
908 finfo->mode = CVAL(p,28);
909 strcpy(finfo->name,p+37);
913 case 260: /* NT uses this, but also accepts 2 */
918 p += 4; /* next entry offset */
919 p += 4; /* fileindex */
921 /* these dates appear to arrive in a weird way. It seems to
922 be localtime plus the serverzone given in the initial
923 connect. This is GMT when DST is not in effect and one
924 hour from GMT otherwise. Can this really be right??
926 I suppose this could be called kludge-GMT. Is is the GMT
927 you get by using the current DST setting on a different
928 localtime. It will be cheap to calculate, I suppose, as
929 no DST tables will be needed */
931 finfo->ctime = interpret_long_date(p); p += 8;
932 finfo->atime = interpret_long_date(p); p += 8;
933 finfo->mtime = interpret_long_date(p); p += 8; p += 8;
934 finfo->size = IVAL(p,0); p += 8;
935 p += 8; /* alloc size */
936 finfo->mode = CVAL(p,0); p += 4;
937 namelen = IVAL(p,0); p += 4;
938 p += 4; /* EA size */
939 p += 2; /* short name len? */
940 p += 24; /* short name? */
941 StrnCpy(finfo->name,p,namelen);
947 DEBUG(1,("Unknown long filename format %d\n",level));
954 /****************************************************************************
955 act on the files in a dir listing
956 ****************************************************************************/
957 static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir)
960 if (!((finfo->mode & aDIR) == 0 && *fileselection &&
961 !mask_match(finfo->name,fileselection,False,False)) &&
962 !(recurse_dir && (strequal(finfo->name,".") ||
963 strequal(finfo->name,".."))))
965 if (recurse_dir && (finfo->mode & aDIR))
969 strcpy(sav_dir,cur_dir);
970 strcat(cur_dir,finfo->name);
971 strcat(cur_dir,"\\");
972 strcpy(mask2,cur_dir);
975 DEBUG(0,("\n%s\n",CNV_LANG(cur_dir)));
980 do_long_dir(inbuf,outbuf,mask2,attribute,fn,True);
982 do_dir(inbuf,outbuf,mask2,attribute,fn,True);
984 strcpy(cur_dir,sav_dir);
988 if (fn && do_this_one(finfo))
995 /****************************************************************************
996 receive a SMB trans or trans2 response allocating the necessary memory
997 ****************************************************************************/
998 static BOOL receive_trans_response(char *inbuf,int trans,
999 int *data_len,int *param_len,
1000 char **data,char **param)
1004 int this_data,this_param;
1006 *data_len = *param_len = 0;
1008 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1012 if (CVAL(inbuf,smb_com) != trans)
1014 DEBUG(0,("Expected %s response, got command 0x%02x\n",
1015 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
1018 if (CVAL(inbuf,smb_rcls) != 0)
1021 /* parse out the lengths */
1022 total_data = SVAL(inbuf,smb_tdrcnt);
1023 total_param = SVAL(inbuf,smb_tprcnt);
1026 *data = Realloc(*data,total_data);
1027 *param = Realloc(*param,total_param);
1031 this_data = SVAL(inbuf,smb_drcnt);
1032 this_param = SVAL(inbuf,smb_prcnt);
1034 memcpy(*data + SVAL(inbuf,smb_drdisp),
1035 smb_base(inbuf) + SVAL(inbuf,smb_droff),
1038 memcpy(*param + SVAL(inbuf,smb_prdisp),
1039 smb_base(inbuf) + SVAL(inbuf,smb_proff),
1041 *data_len += this_data;
1042 *param_len += this_param;
1044 /* parse out the total lengths again - they can shrink! */
1045 total_data = SVAL(inbuf,smb_tdrcnt);
1046 total_param = SVAL(inbuf,smb_tprcnt);
1048 if (total_data <= *data_len && total_param <= *param_len)
1051 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1055 if (CVAL(inbuf,smb_com) != trans)
1057 DEBUG(0,("Expected %s response, got command 0x%02x\n",
1058 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
1061 if (CVAL(inbuf,smb_rcls) != 0)
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 (!chkpath(rname,False) && !do_mkdir(rname)) {
2136 if (!seek_list(f,lname))
2145 sprintf(quest,"Put file %s? ",lname);
2146 if (prompt && !yesno(quest)) continue;
2148 strcpy(rname,cur_dir);
2149 strcat(rname,lname);
2153 /* null size so do_put knows to ignore it */
2156 /* set the date on the file */
2157 finfo.mtime = st.st_mtime;
2159 do_put(rname,lname,&finfo);
2166 /****************************************************************************
2168 ****************************************************************************/
2169 static void do_cancel(int job)
2171 char *rparam = NULL;
2177 bzero(param,sizeof(param));
2180 SSVAL(p,0,81); /* api number */
2183 p = skip_string(p,1);
2185 p = skip_string(p,1);
2189 if (call_api(PTR_DIFF(p,param),0,
2195 int res = SVAL(rparam,0);
2198 printf("Job %d cancelled\n",job);
2200 printf("Error %d calcelling job %d\n",res,job);
2204 printf("Server refused cancel request\n");
2206 if (rparam) free(rparam);
2207 if (rdata) free(rdata);
2213 /****************************************************************************
2215 ****************************************************************************/
2216 static void cmd_cancel(char *inbuf,char *outbuf )
2221 if (!connect_as_printer)
2223 DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
2224 DEBUG(0,("Trying to cancel print jobs without -P may fail\n"));
2227 if (!next_token(NULL,buf,NULL)) {
2228 printf("cancel <jobid> ...\n");
2234 } while (next_token(NULL,buf,NULL));
2238 /****************************************************************************
2240 ****************************************************************************/
2241 static void cmd_stat(char *inbuf,char *outbuf)
2245 char *resp_data=NULL;
2246 char *resp_param=NULL;
2247 int resp_data_len = 0;
2248 int resp_param_len=0;
2250 uint16 setup = TRANSACT2_QPATHINFO;
2252 if (!next_token(NULL,buf,NULL)) {
2253 printf("stat <file>\n");
2258 SSVAL(param,0,4); /* level */
2263 send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
2265 0,6 + strlen(p)+1,1,
2268 receive_trans_response(inbuf,SMBtrans2,
2269 &resp_data_len,&resp_param_len,
2270 &resp_data,&resp_param);
2272 if (resp_data) free(resp_data); resp_data = NULL;
2273 if (resp_param) free(resp_param); resp_param = NULL;
2277 /****************************************************************************
2279 ****************************************************************************/
2280 static void cmd_print(char *inbuf,char *outbuf )
2289 if (!connect_as_printer)
2291 DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
2292 DEBUG(0,("Trying to print without -P may fail\n"));
2295 if (!next_token(NULL,lname,NULL))
2297 DEBUG(0,("print <filename>\n"));
2301 strcpy(rname,lname);
2302 p = strrchr(rname,'/');
2307 strcpy(rname,tname);
2310 if ((int)strlen(rname) > 14)
2313 if (strequal(lname,"-"))
2316 strcpy(rname,"stdin");
2319 dos_clean_name(rname);
2321 bzero(outbuf,smb_size);
2322 set_message(outbuf,2,2 + strlen(rname),True);
2324 CVAL(outbuf,smb_com) = SMBsplopen;
2325 SSVAL(outbuf,smb_tid,cnum);
2328 SSVAL(outbuf,smb_vwv0,0);
2329 SSVAL(outbuf,smb_vwv1,printmode);
2331 p = smb_buf(outbuf);
2335 send_smb(Client,outbuf);
2336 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2338 if (CVAL(inbuf,smb_rcls) != 0)
2340 DEBUG(0,("%s opening printer for %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
2345 f = fopen(lname,"r");
2348 DEBUG(0,("Error opening local file %s\n",lname));
2353 fnum = SVAL(inbuf,smb_vwv0);
2355 DEBUG(1,("printing file %s as %s\n",lname,CNV_LANG(rname)));
2361 bzero(outbuf,smb_size);
2362 set_message(outbuf,1,3,True);
2364 /* for some strange reason the OS/2 print server can't handle large
2365 packets when printing. weird */
2366 n = MIN(1024,max_xmit-(smb_len(outbuf)+4));
2369 n = printread(f,smb_buf(outbuf)+3,(int)(0.95*n));
2371 n = readfile(smb_buf(outbuf)+3,1,n,f);
2374 DEBUG(0,("read gave %d\n",n));
2378 smb_setlen(outbuf,smb_len(outbuf) + n);
2380 CVAL(outbuf,smb_com) = SMBsplwr;
2381 SSVAL(outbuf,smb_tid,cnum);
2384 SSVAL(outbuf,smb_vwv0,fnum);
2385 SSVAL(outbuf,smb_vwv1,n+3);
2386 CVAL(smb_buf(outbuf),0) = 1;
2387 SSVAL(smb_buf(outbuf),1,n);
2389 send_smb(Client,outbuf);
2390 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2392 if (CVAL(inbuf,smb_rcls) != 0)
2394 DEBUG(0,("%s printing remote file\n",smb_errstr(inbuf)));
2401 DEBUG(2,("%d bytes printed\n",nread));
2403 bzero(outbuf,smb_size);
2404 set_message(outbuf,1,0,True);
2405 CVAL(outbuf,smb_com) = SMBsplclose;
2406 SSVAL(outbuf,smb_tid,cnum);
2409 SSVAL(outbuf,smb_vwv0,fnum);
2411 send_smb(Client,outbuf);
2412 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2414 if (CVAL(inbuf,smb_rcls) != 0)
2416 DEBUG(0,("%s closing print file\n",smb_errstr(inbuf)));
2426 /****************************************************************************
2428 ****************************************************************************/
2429 static void cmd_queue(char *inbuf,char *outbuf )
2434 bzero(outbuf,smb_size);
2435 set_message(outbuf,2,0,True);
2437 CVAL(outbuf,smb_com) = SMBsplretq;
2438 SSVAL(outbuf,smb_tid,cnum);
2441 SSVAL(outbuf,smb_vwv0,32); /* a max of 20 entries is to be shown */
2442 SSVAL(outbuf,smb_vwv1,0); /* the index into the queue */
2444 send_smb(Client,outbuf);
2445 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2447 if (CVAL(inbuf,smb_rcls) != 0)
2449 DEBUG(0,("%s obtaining print queue\n",smb_errstr(inbuf)));
2453 count = SVAL(inbuf,smb_vwv0);
2454 p = smb_buf(inbuf) + 3;
2457 DEBUG(0,("No entries in the print queue\n"));
2464 DEBUG(0,("Job Name Size Status\n"));
2470 case 0x01: sprintf(status,"held or stopped"); break;
2471 case 0x02: sprintf(status,"printing"); break;
2472 case 0x03: sprintf(status,"awaiting print"); break;
2473 case 0x04: sprintf(status,"in intercept"); break;
2474 case 0x05: sprintf(status,"file had error"); break;
2475 case 0x06: sprintf(status,"printer error"); break;
2476 default: sprintf(status,"unknown"); break;
2479 DEBUG(0,("%-6d %-16.16s %-9d %s\n",
2480 SVAL(p,5),p+12,IVAL(p,7),status));
2488 /****************************************************************************
2490 ****************************************************************************/
2491 static void do_del(file_info *finfo)
2494 char *inbuf,*outbuf;
2497 strcpy(mask,cur_dir);
2498 strcat(mask,finfo->name);
2500 if (finfo->mode & aDIR)
2503 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2504 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2506 if (!inbuf || !outbuf)
2508 DEBUG(0,("out of memory\n"));
2512 bzero(outbuf,smb_size);
2513 set_message(outbuf,1,2 + strlen(mask),True);
2515 CVAL(outbuf,smb_com) = SMBunlink;
2516 SSVAL(outbuf,smb_tid,cnum);
2519 SSVAL(outbuf,smb_vwv0,0);
2521 p = smb_buf(outbuf);
2525 send_smb(Client,outbuf);
2526 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2528 if (CVAL(inbuf,smb_rcls) != 0)
2529 DEBUG(0,("%s deleting remote file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
2531 free(inbuf);free(outbuf);
2535 /****************************************************************************
2537 ****************************************************************************/
2538 static void cmd_del(char *inbuf,char *outbuf )
2542 int attribute = aSYSTEM | aHIDDEN;
2547 strcpy(mask,cur_dir);
2549 if (!next_token(NULL,buf,NULL))
2551 DEBUG(0,("del <filename>\n"));
2556 do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_del,False);
2560 /****************************************************************************
2562 ****************************************************************************/
2563 static void cmd_rmdir(char *inbuf,char *outbuf )
2569 strcpy(mask,cur_dir);
2571 if (!next_token(NULL,buf,NULL))
2573 DEBUG(0,("rmdir <dirname>\n"));
2578 bzero(outbuf,smb_size);
2579 set_message(outbuf,0,2 + strlen(mask),True);
2581 CVAL(outbuf,smb_com) = SMBrmdir;
2582 SSVAL(outbuf,smb_tid,cnum);
2586 p = smb_buf(outbuf);
2590 send_smb(Client,outbuf);
2591 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2593 if (CVAL(inbuf,smb_rcls) != 0)
2595 DEBUG(0,("%s removing remote directory file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
2601 /****************************************************************************
2603 ****************************************************************************/
2604 static void cmd_rename(char *inbuf,char *outbuf )
2610 strcpy(src,cur_dir);
2611 strcpy(dest,cur_dir);
2613 if (!next_token(NULL,buf,NULL) || !next_token(NULL,buf2,NULL))
2615 DEBUG(0,("rename <src> <dest>\n"));
2621 bzero(outbuf,smb_size);
2622 set_message(outbuf,1,4 + strlen(src) + strlen(dest),True);
2624 CVAL(outbuf,smb_com) = SMBmv;
2625 SSVAL(outbuf,smb_tid,cnum);
2626 SSVAL(outbuf,smb_vwv0,aHIDDEN | aDIR | aSYSTEM);
2629 p = smb_buf(outbuf);
2632 p = skip_string(p,1);
2636 send_smb(Client,outbuf);
2637 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2639 if (CVAL(inbuf,smb_rcls) != 0)
2641 DEBUG(0,("%s renaming files\n",smb_errstr(inbuf)));
2648 /****************************************************************************
2649 toggle the prompt flag
2650 ****************************************************************************/
2651 static void cmd_prompt(void)
2654 DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
2658 /****************************************************************************
2659 set the newer than time
2660 ****************************************************************************/
2661 static void cmd_newer(void)
2667 ok = next_token(NULL,buf,NULL);
2668 if (ok && (sys_stat(buf,&sbuf) == 0))
2670 newer_than = sbuf.st_mtime;
2671 DEBUG(1,("Getting files newer than %s",
2672 asctime(LocalTime(&newer_than))));
2677 if (ok && newer_than == 0)
2678 DEBUG(0,("Error setting newer-than time\n"));
2681 /****************************************************************************
2682 set the archive level
2683 ****************************************************************************/
2684 static void cmd_archive(void)
2688 if (next_token(NULL,buf,NULL)) {
2689 archive_level = atoi(buf);
2691 DEBUG(0,("Archive level is %d\n",archive_level));
2694 /****************************************************************************
2695 toggle the lowercaseflag
2696 ****************************************************************************/
2697 static void cmd_lowercase(void)
2699 lowercase = !lowercase;
2700 DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
2706 /****************************************************************************
2707 toggle the recurse flag
2708 ****************************************************************************/
2709 static void cmd_recurse(void)
2712 DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
2715 /****************************************************************************
2716 toggle the translate flag
2717 ****************************************************************************/
2718 static void cmd_translate(void)
2720 translation = !translation;
2721 DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
2722 translation?"on":"off"));
2726 /****************************************************************************
2727 do a printmode command
2728 ****************************************************************************/
2729 static void cmd_printmode(void)
2734 if (next_token(NULL,buf,NULL))
2736 if (strequal(buf,"text"))
2740 if (strequal(buf,"graphics"))
2743 printmode = atoi(buf);
2750 strcpy(mode,"text");
2753 strcpy(mode,"graphics");
2756 sprintf(mode,"%d",printmode);
2760 DEBUG(2,("the printmode is now %s\n",mode));
2763 /****************************************************************************
2765 ****************************************************************************/
2766 static void cmd_lcd(void)
2771 if (next_token(NULL,buf,NULL))
2773 DEBUG(2,("the local directory is now %s\n",GetWd(d)));
2777 /****************************************************************************
2778 send a session request
2779 ****************************************************************************/
2780 static BOOL send_session_request(char *inbuf,char *outbuf)
2785 /* send a session request (RFC 8002) */
2787 strcpy(dest,desthost);
2788 p = strchr(dest,'.');
2791 /* put in the destination name */
2793 name_mangle(dest,p,name_type);
2798 name_mangle(myname,p,0);
2801 /* setup the packet length */
2802 _smb_setlen(outbuf,len);
2803 CVAL(outbuf,0) = 0x81;
2805 send_smb(Client,outbuf);
2806 DEBUG(5,("Sent session request\n"));
2808 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2810 if (CVAL(inbuf,0) == 0x84) /* C. Hoch 9/14/95 Start */
2812 /* For information, here is the response structure.
2813 * We do the byte-twiddling to for portability.
2814 struct RetargetResponse{
2816 unsigned char flags;
2823 int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
2824 /* SESSION RETARGET */
2825 putip((char *)&dest_ip,inbuf+4);
2828 Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
2832 DEBUG(3,("Retargeted\n"));
2834 set_socket_options(Client,user_socket_options);
2837 return send_session_request(inbuf,outbuf);
2838 } /* C. Hoch 9/14/95 End */
2841 if (CVAL(inbuf,0) != 0x82)
2843 int ecode = CVAL(inbuf,4);
2844 DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
2845 CVAL(inbuf,0),ecode,myname,desthost));
2849 DEBUG(0,("Not listening on called name\n"));
2850 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
2851 DEBUG(0,("You may find the -I option useful for this\n"));
2854 DEBUG(0,("Not listening for calling name\n"));
2855 DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
2856 DEBUG(0,("You may find the -n option useful for this\n"));
2859 DEBUG(0,("Called name not present\n"));
2860 DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
2861 DEBUG(0,("You may find the -I option useful for this\n"));
2864 DEBUG(0,("Called name present, but insufficient resources\n"));
2865 DEBUG(0,("Perhaps you should try again later?\n"));
2868 DEBUG(0,("Unspecified error 0x%X\n",ecode));
2869 DEBUG(0,("Your server software is being unfriendly\n"));
2881 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
2882 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
2883 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
2884 {PROTOCOL_LANMAN1,"LANMAN1.0"},
2885 {PROTOCOL_LANMAN2,"LM1.2X002"},
2886 {PROTOCOL_LANMAN2,"Samba"},
2887 {PROTOCOL_NT1,"NT LM 0.12"},
2888 {PROTOCOL_NT1,"NT LANMAN 1.0"},
2893 /****************************************************************************
2894 send a login command
2895 ****************************************************************************/
2896 static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
2898 BOOL was_null = (!inbuf && !outbuf);
2900 time_t servertime = 0;
2901 extern int serverzone;
2912 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2913 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2917 if (strstr(service,"IPC$")) connect_as_ipc = True;
2921 if (connect_as_printer)
2922 strcpy(dev,"LPT1:");
2927 if (start_session && !send_session_request(inbuf,outbuf))
2937 bzero(outbuf,smb_size);
2939 /* setup the protocol strings */
2943 for (plength=0,numprots=0;
2944 prots[numprots].name && prots[numprots].prot<=max_protocol;
2946 plength += strlen(prots[numprots].name)+2;
2948 set_message(outbuf,0,plength,True);
2950 p = smb_buf(outbuf);
2952 prots[numprots].name && prots[numprots].prot<=max_protocol;
2956 strcpy(p,prots[numprots].name);
2961 CVAL(outbuf,smb_com) = SMBnegprot;
2964 CVAL(smb_buf(outbuf),0) = 2;
2966 send_smb(Client,outbuf);
2967 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2971 if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
2973 DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
2974 myname,desthost,smb_errstr(inbuf)));
2983 Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
2986 if (Protocol < PROTOCOL_NT1) {
2987 sec_mode = SVAL(inbuf,smb_vwv1);
2988 max_xmit = SVAL(inbuf,smb_vwv2);
2989 sesskey = IVAL(inbuf,smb_vwv6);
2990 serverzone = SVALS(inbuf,smb_vwv10)*60;
2991 /* this time is converted to GMT by make_unix_date */
2992 servertime = make_unix_date(inbuf+smb_vwv8);
2993 if (Protocol >= PROTOCOL_COREPLUS) {
2994 readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
2995 writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
2997 crypt_len = smb_buflen(inbuf);
2998 memcpy(cryptkey,smb_buf(inbuf),8);
2999 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
3000 max_vcs = SVAL(inbuf,smb_vwv4);
3001 DEBUG(3,("max vcs %d\n",max_vcs));
3002 DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
3005 sec_mode = CVAL(inbuf,smb_vwv1);
3006 max_xmit = IVAL(inbuf,smb_vwv3+1);
3007 sesskey = IVAL(inbuf,smb_vwv7+1);
3008 serverzone = SVALS(inbuf,smb_vwv15+1)*60;
3009 /* this time arrives in real GMT */
3010 servertime = interpret_long_date(inbuf+smb_vwv11+1);
3011 crypt_len = CVAL(inbuf,smb_vwv16+1);
3012 memcpy(cryptkey,smb_buf(inbuf),8);
3013 if (IVAL(inbuf,smb_vwv9+1) & 1)
3014 readbraw_supported = writebraw_supported = True;
3015 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
3016 max_vcs = SVAL(inbuf,smb_vwv2+1);
3017 DEBUG(3,("max vcs %d\n",max_vcs));
3018 DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
3019 DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
3022 DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
3023 DEBUG(3,("max xmt %d\n",max_xmit));
3024 DEBUG(3,("Got %d byte crypt key\n",crypt_len));
3025 DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
3027 doencrypt = ((sec_mode & 2) != 0);
3030 static BOOL done_time = False;
3032 DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
3033 asctime(LocalTime(&servertime)),
3034 -(double)(serverzone/3600.0)));
3044 pass = (char *)getpass("Password: ");
3046 if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
3049 int passlen = strlen(pass)+1;
3053 if (doencrypt && *pass) {
3054 DEBUG(3,("Using encrypted passwords\n"));
3056 SMBencrypt(pass,cryptkey,pword);
3062 /* if in share level security then don't send a password now */
3063 if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;}
3065 /* send a session setup command */
3066 bzero(outbuf,smb_size);
3068 if (Protocol < PROTOCOL_NT1) {
3069 set_message(outbuf,10,1 + strlen(username) + passlen,True);
3070 CVAL(outbuf,smb_com) = SMBsesssetupX;
3073 CVAL(outbuf,smb_vwv0) = 0xFF;
3074 SSVAL(outbuf,smb_vwv2,max_xmit);
3075 SSVAL(outbuf,smb_vwv3,2);
3076 SSVAL(outbuf,smb_vwv4,max_vcs-1);
3077 SIVAL(outbuf,smb_vwv5,sesskey);
3078 SSVAL(outbuf,smb_vwv7,passlen);
3079 p = smb_buf(outbuf);
3080 memcpy(p,pword,passlen);
3084 if (!doencrypt) passlen--;
3086 set_message(outbuf,13,0,True);
3087 CVAL(outbuf,smb_com) = SMBsesssetupX;
3090 CVAL(outbuf,smb_vwv0) = 0xFF;
3091 SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
3092 SSVAL(outbuf,smb_vwv3,2);
3093 SSVAL(outbuf,smb_vwv4,getpid());
3094 SIVAL(outbuf,smb_vwv5,sesskey);
3095 SSVAL(outbuf,smb_vwv7,passlen);
3096 SSVAL(outbuf,smb_vwv8,0);
3097 p = smb_buf(outbuf);
3098 memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
3099 strcpy(p,username);p = skip_string(p,1);
3100 strcpy(p,workgroup);p = skip_string(p,1);
3101 strcpy(p,"Unix");p = skip_string(p,1);
3102 strcpy(p,"Samba");p = skip_string(p,1);
3103 set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
3106 send_smb(Client,outbuf);
3107 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
3111 if (CVAL(inbuf,smb_rcls) != 0)
3114 ((CVAL(inbuf,smb_rcls) == ERRDOS &&
3115 SVAL(inbuf,smb_err) == ERRnoaccess) ||
3116 (CVAL(inbuf,smb_rcls) == ERRSRV &&
3117 SVAL(inbuf,smb_err) == ERRbadpw)))
3120 DEBUG(3,("resending login\n"));
3124 DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
3125 username,myname,desthost,smb_errstr(inbuf)));
3126 DEBUG(0,("You might find the -U, -W or -n options useful\n"));
3127 DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
3128 DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
3137 if (Protocol >= PROTOCOL_NT1) {
3138 char *domain,*os,*lanman;
3141 lanman = skip_string(os,1);
3142 domain = skip_string(lanman,1);
3143 if (*domain || *os || *lanman)
3144 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
3147 /* use the returned uid from now on */
3148 if (SVAL(inbuf,smb_uid) != uid)
3149 DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
3150 SVAL(inbuf,smb_uid),uid));
3151 uid = SVAL(inbuf,smb_uid);
3154 /* now we've got a connection - send a tcon message */
3155 bzero(outbuf,smb_size);
3157 if (strncmp(service,"\\\\",2) != 0)
3159 DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
3160 DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
3167 int passlen = strlen(pass)+1;
3172 if (doencrypt && *pass) {
3174 SMBencrypt(pass,cryptkey,pword);
3178 /* if in user level security then don't send a password now */
3179 if ((sec_mode & 1)) {
3180 strcpy(pword, ""); passlen=1;
3183 if (Protocol <= PROTOCOL_CORE) {
3184 set_message(outbuf,0,6 + strlen(service) + passlen + strlen(dev),True);
3185 CVAL(outbuf,smb_com) = SMBtcon;
3188 p = smb_buf(outbuf);
3191 p = skip_string(p,1);
3193 memcpy(p,pword,passlen);
3199 set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
3200 CVAL(outbuf,smb_com) = SMBtconX;
3203 SSVAL(outbuf,smb_vwv0,0xFF);
3204 SSVAL(outbuf,smb_vwv3,passlen);
3206 p = smb_buf(outbuf);
3207 memcpy(p,pword,passlen);
3210 p = skip_string(p,1);
3215 send_smb(Client,outbuf);
3216 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
3218 /* trying again with a blank password */
3219 if (CVAL(inbuf,smb_rcls) != 0 &&
3220 (int)strlen(pass) > 0 &&
3222 Protocol >= PROTOCOL_LANMAN1)
3224 DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
3229 if (CVAL(inbuf,smb_rcls) != 0)
3231 DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
3232 DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
3233 DEBUG(0,("Some servers insist that these be in uppercase\n"));
3243 if (Protocol <= PROTOCOL_CORE) {
3244 max_xmit = SVAL(inbuf,smb_vwv0);
3246 cnum = SVAL(inbuf,smb_vwv1);
3249 max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
3251 max_xmit = BUFFER_SIZE - 4;
3253 cnum = SVAL(inbuf,smb_tid);
3256 DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
3267 /****************************************************************************
3268 send a logout command
3269 ****************************************************************************/
3270 static void send_logout(void )
3272 pstring inbuf,outbuf;
3274 bzero(outbuf,smb_size);
3275 set_message(outbuf,0,0,True);
3276 CVAL(outbuf,smb_com) = SMBtdis;
3277 SSVAL(outbuf,smb_tid,cnum);
3280 send_smb(Client,outbuf);
3281 receive_smb(Client,inbuf,SHORT_TIMEOUT);
3283 if (CVAL(inbuf,smb_rcls) != 0)
3285 DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
3297 /****************************************************************************
3299 ****************************************************************************/
3300 static BOOL call_api(int prcnt,int drcnt,
3301 int mprcnt,int mdrcnt,
3302 int *rprcnt,int *rdrcnt,
3303 char *param,char *data,
3304 char **rparam,char **rdata)
3306 static char *inbuf=NULL;
3307 static char *outbuf=NULL;
3309 if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3310 if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3312 send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0,
3317 return (receive_trans_response(inbuf,SMBtrans,
3322 /****************************************************************************
3323 send a SMB trans or trans2 request
3324 ****************************************************************************/
3325 static BOOL send_trans_request(char *outbuf,int trans,
3326 char *name,int fid,int flags,
3327 char *data,char *param,uint16 *setup,
3328 int ldata,int lparam,int lsetup,
3329 int mdata,int mparam,int msetup)
3332 int this_ldata,this_lparam;
3333 int tot_data=0,tot_param=0;
3334 char *outdata,*outparam;
3338 this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
3339 this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
3341 bzero(outbuf,smb_size);
3342 set_message(outbuf,14+lsetup,0,True);
3343 CVAL(outbuf,smb_com) = trans;
3344 SSVAL(outbuf,smb_tid,cnum);
3347 outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
3348 outdata = outparam+this_lparam;
3350 /* primary request */
3351 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
3352 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
3353 SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
3354 SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
3355 SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
3356 SSVAL(outbuf,smb_flags,flags); /* flags */
3357 SIVAL(outbuf,smb_timeout,0); /* timeout */
3358 SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
3359 SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
3360 SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
3361 SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
3362 SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
3363 for (i=0;i<lsetup;i++) /* setup[] */
3364 SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
3365 p = smb_buf(outbuf);
3366 if (trans==SMBtrans)
3367 strcpy(p,name); /* name[] */
3370 *p++ = 0; /* put in a null smb_name */
3371 *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
3373 if (this_lparam) /* param[] */
3374 memcpy(outparam,param,this_lparam);
3375 if (this_ldata) /* data[] */
3376 memcpy(outdata,data,this_ldata);
3377 set_message(outbuf,14+lsetup, /* wcnt, bcc */
3378 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
3381 send_smb(Client,outbuf);
3383 if (this_ldata < ldata || this_lparam < lparam)
3385 /* receive interim response */
3386 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
3388 DEBUG(0,("%s request failed (%s)\n",
3389 trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
3393 tot_data = this_ldata;
3394 tot_param = this_lparam;
3396 while (tot_data < ldata || tot_param < lparam)
3398 this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
3399 this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
3401 set_message(outbuf,trans==SMBtrans?8:9,0,True);
3402 CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
3404 outparam = smb_buf(outbuf);
3405 outdata = outparam+this_lparam;
3407 /* secondary request */
3408 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
3409 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
3410 SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
3411 SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
3412 SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
3413 SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
3414 SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
3415 SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
3416 if (trans==SMBtrans2)
3417 SSVAL(outbuf,smb_sfid,fid); /* fid */
3418 if (this_lparam) /* param[] */
3419 memcpy(outparam,param,this_lparam);
3420 if (this_ldata) /* data[] */
3421 memcpy(outdata,data,this_ldata);
3422 set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
3423 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
3426 send_smb(Client,outbuf);
3428 tot_data += this_ldata;
3429 tot_param += this_lparam;
3436 /****************************************************************************
3437 try and browse available connections on a host
3438 ****************************************************************************/
3439 static BOOL browse_host(BOOL sort)
3442 #define strcasecmp StrCaseCmp
3444 extern int strcasecmp();
3446 char *rparam = NULL;
3453 /* now send a SMBtrans command with api RNetShareEnum */
3455 SSVAL(p,0,0); /* api number */
3458 p = skip_string(p,1);
3460 p = skip_string(p,1);
3462 SSVAL(p,2,BUFFER_SIZE);
3465 if (call_api(PTR_DIFF(p,param),0,
3471 int res = SVAL(rparam,0);
3472 int converter=SVAL(rparam,2);
3474 BOOL long_share_name=False;
3478 count=SVAL(rparam,4);
3483 printf("\n\tSharename Type Comment\n");
3484 printf("\t--------- ---- -------\n");
3488 qsort(p,count,20,QSORT_CAST strcasecmp);
3490 for (i=0;i<count;i++)
3493 int type = SVAL(p,14);
3494 int comment_offset = IVAL(p,16) & 0xFFFF;
3500 case STYPE_DISKTREE:
3501 strcpy(typestr,"Disk"); break;
3503 strcpy(typestr,"Printer"); break;
3505 strcpy(typestr,"Device"); break;
3507 strcpy(typestr,"IPC"); break;
3510 printf("\t%-15.15s%-10.10s%s\n",
3513 comment_offset?rdata+comment_offset-converter:"");
3515 if (strlen(sname)>8) long_share_name=True;
3520 if (long_share_name) {
3521 printf("\nNOTE: There were share names longer than 8 chars.\nOn older clients these may not be accessible or may give browsing errors\n");
3526 if (rparam) free(rparam);
3527 if (rdata) free(rdata);
3533 /****************************************************************************
3534 get some server info
3535 ****************************************************************************/
3536 static void server_info()
3538 char *rparam = NULL;
3544 bzero(param,sizeof(param));
3547 SSVAL(p,0,63); /* api number */
3550 p = skip_string(p,1);
3551 strcpy(p,"zzzBBzz");
3552 p = skip_string(p,1);
3553 SSVAL(p,0,10); /* level 10 */
3557 if (call_api(PTR_DIFF(p,param),0,
3563 int res = SVAL(rparam,0);
3564 int converter=SVAL(rparam,2);
3570 printf("\nServer=[%s] User=[%s] Workgroup=[%s] Domain=[%s]\n",
3571 rdata+SVAL(p,0)-converter,
3572 rdata+SVAL(p,4)-converter,
3573 rdata+SVAL(p,8)-converter,
3574 rdata+SVAL(p,14)-converter);
3578 if (rparam) free(rparam);
3579 if (rdata) free(rdata);
3585 /****************************************************************************
3586 try and browse available connections on a host
3587 ****************************************************************************/
3588 static BOOL list_servers(char *wk_grp)
3590 char *rparam = NULL;
3599 /* now send a SMBtrans command with api ServerEnum? */
3601 SSVAL(p,0,0x68); /* api number */
3603 strcpy(p,"WrLehDz");
3604 p = skip_string(p,1);
3606 strcpy(p,"B16BBDz");
3608 strcpy(p,getenv("XX_STR2"));
3611 p = skip_string(p,1);
3613 SSVAL(p,2,0x2000); /* buf length */
3616 SIVAL(p,0,SV_TYPE_ALL);
3621 p = skip_string(p,1);
3623 if (call_api(PTR_DIFF(p+4,param),0,
3629 int res = SVAL(rparam,0);
3630 int converter=SVAL(rparam,2);
3635 count=SVAL(rparam,4);
3638 printf("\n\nThis machine has a browse list:\n");
3639 printf("\n\tServer Comment\n");
3640 printf("\t--------- -------\n");
3643 for (i=0;i<count;i++) {
3645 int comment_offset = IVAL(p2,22) & 0xFFFF;
3646 printf("\t%-16.16s %s\n",
3648 comment_offset?rdata+comment_offset-converter:"");
3656 if (rparam) {free(rparam); rparam = NULL;}
3657 if (rdata) {free(rdata); rdata = NULL;}
3659 SIVAL(p,0,0x7fffffff);
3661 if (call_api(PTR_DIFF(p+4,param),0,
3667 int res = SVAL(rparam,0);
3668 int converter=SVAL(rparam,2);
3673 count=SVAL(rparam,4);
3676 printf("\n\nThis machine has a workgroup list:\n");
3677 printf("\n\tWorkgroup Master\n");
3678 printf("\t--------- -------\n");
3681 for (i=0;i<count;i++) {
3683 int comment_offset = IVAL(p2,22) & 0xFFFF;
3684 printf("\t%-16.16s %s\n",
3686 comment_offset?rdata+comment_offset-converter:"");
3694 if (rparam) free(rparam);
3695 if (rdata) free(rdata);
3701 /* This defines the commands supported by this client */
3709 {"ls",cmd_dir,"<mask> list the contents of the current directory"},
3710 {"dir",cmd_dir,"<mask> list the contents of the current directory"},
3711 {"lcd",cmd_lcd,"[directory] change/report the local current working directory"},
3712 {"cd",cmd_cd,"[directory] change/report the remote directory"},
3713 {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)"},
3714 {"get",cmd_get,"<remote name> [local name] get a file"},
3715 {"mget",cmd_mget,"<mask> get all the matching files"},
3716 {"put",cmd_put,"<local name> [remote name] put a file"},
3717 {"mput",cmd_mput,"<mask> put all matching files"},
3718 {"rename",cmd_rename,"<src> <dest> rename some files"},
3719 {"more",cmd_more,"<remote name> view a remote file with your pager"},
3720 {"mask",cmd_select,"<mask> mask all filenames against this"},
3721 {"del",cmd_del,"<mask> delete all matching files"},
3722 {"rm",cmd_del,"<mask> delete all matching files"},
3723 {"mkdir",cmd_mkdir,"<directory> make a directory"},
3724 {"md",cmd_mkdir,"<directory> make a directory"},
3725 {"rmdir",cmd_rmdir,"<directory> remove a directory"},
3726 {"rd",cmd_rmdir,"<directory> remove a directory"},
3727 {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput"},
3728 {"recurse",cmd_recurse,"toggle directory recursion for mget and mput"},
3729 {"translate",cmd_translate,"toggle text translation for printing"},
3730 {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get"},
3731 {"print",cmd_print,"<file name> print a file"},
3732 {"printmode",cmd_printmode,"<graphics or text> set the print mode"},
3733 {"queue",cmd_queue,"show the print queue"},
3734 {"cancel",cmd_cancel,"<jobid> cancel a print queue entry"},
3735 {"stat",cmd_stat,"<file> get info on a file (experimental!)"},
3736 {"quit",send_logout,"logoff the server"},
3737 {"q",send_logout,"logoff the server"},
3738 {"exit",send_logout,"logoff the server"},
3739 {"newer",cmd_newer,"<file> only mget files newer than the specified local file"},
3740 {"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"},
3741 {"tar",cmd_tar,"tar <c|x>[IXbgNa] current directory to/from <file name>" },
3742 {"blocksize",cmd_block,"blocksize <number> (default 20)" },
3743 {"tarmode",cmd_tarmode,
3744 "<full|inc|reset|noreset> tar's behaviour towards archive bits" },
3745 {"setmode",cmd_setmode,"filename <setmode string> change modes of file"},
3746 {"help",cmd_help,"[command] give help on a command"},
3747 {"?",cmd_help,"[command] give help on a command"},
3748 {"!",NULL,"run a shell command on the local system"},
3753 /*******************************************************************
3754 lookup a command string in the list of commands, including
3756 ******************************************************************/
3757 static int process_tok(fstring tok)
3759 int i = 0, matches = 0;
3761 int tok_len = strlen(tok);
3763 while (commands[i].fn != NULL)
3765 if (strequal(commands[i].name,tok))
3771 else if (strnequal(commands[i].name, tok, tok_len+1))
3781 else if (matches == 1)
3787 /****************************************************************************
3789 ****************************************************************************/
3795 if (next_token(NULL,buf,NULL))
3797 if ((i = process_tok(buf)) >= 0)
3798 DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));
3801 while (commands[i].description)
3803 for (j=0; commands[i].description && (j<5); j++) {
3804 DEBUG(0,("%-15s",commands[i].name));
3811 /****************************************************************************
3812 open the client sockets
3813 ****************************************************************************/
3814 static BOOL open_sockets(int port )
3816 static int last_port;
3824 if (port == 0) port=last_port;
3835 strcpy(service2,service);
3836 host = strtok(service2,"\\/");
3838 DEBUG(0,("Badly formed host name\n"));
3841 strcpy(desthost,host);
3846 get_myname(myname,NULL);
3850 DEBUG(3,("Opening sockets\n"));
3856 if ((hp = Get_Hostbyname(host))) {
3857 putip((char *)&dest_ip,(char *)hp->h_addr);
3861 /* Try and resolve the name with the netbios server */
3864 if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) {
3865 set_socket_options(bcast, "SO_BROADCAST");
3867 if (name_query(bcast, host, 0x20, True, True, *iface_bcast(dest_ip),
3875 DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
3881 Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
3885 DEBUG(3,("Connected\n"));
3887 set_socket_options(Client,user_socket_options);
3892 /****************************************************************************
3893 wait for keyboard activity, swallowing network packets
3894 ****************************************************************************/
3896 static char wait_keyboard(char *buffer)
3898 static void wait_keyboard(char *buffer)
3903 struct timeval timeout;
3913 FD_SET(Client,&fds);
3915 FD_SET(fileno(stdin),&fds);
3918 timeout.tv_sec = 20;
3919 timeout.tv_usec = 0;
3923 selrtn = sys_select(&fds,&timeout);
3926 if (FD_ISSET(fileno(stdin),&fds))
3934 f_flags = fcntl(fileno(stdin), F_GETFL, 0);
3935 fcntl( fileno(stdin), F_SETFL, f_flags | O_NONBLOCK);
3936 readret = read_data( fileno(stdin), &ch, 1);
3937 fcntl(fileno(stdin), F_SETFL, f_flags);
3940 if (errno != EAGAIN)
3942 /* should crash here */
3943 DEBUG(1,("readchar stdin failed\n"));
3946 else if (readret != 0)
3952 if (FD_ISSET(Client,&fds))
3953 receive_smb(Client,buffer,0);
3960 chkpath("\\",False);
3963 chkpath("\\",False);
3969 /****************************************************************************
3970 close and open the connection again
3971 ****************************************************************************/
3972 BOOL reopen_connection(char *inbuf,char *outbuf)
3974 static int open_count=0;
3978 if (open_count>5) return(False);
3980 DEBUG(1,("Trying to re-open connection\n"));
3982 set_message(outbuf,0,0,True);
3983 SCVAL(outbuf,smb_com,SMBtdis);
3984 SSVAL(outbuf,smb_tid,cnum);
3987 send_smb(Client,outbuf);
3988 receive_smb(Client,inbuf,SHORT_TIMEOUT);
3991 if (!open_sockets(0)) return(False);
3993 return(send_login(inbuf,outbuf,True,True));
3996 /****************************************************************************
3997 process commands from the client
3998 ****************************************************************************/
3999 static BOOL process(char *base_directory)
4005 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4006 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4008 if ((InBuffer == NULL) || (OutBuffer == NULL))
4011 bzero(OutBuffer,smb_size);
4013 if (!send_login(InBuffer,OutBuffer,True,True))
4016 if (*base_directory) do_cd(base_directory);
4019 if (cmd[0] != '\0') while (cmd[0] != '\0')
4025 if ((p = strchr(cmd, ';')) == 0)
4027 strncpy(line, cmd, 999);
4033 if (p - cmd > 999) p = cmd + 999;
4034 strncpy(line, cmd, p - cmd);
4035 line[p - cmd] = '\0';
4039 /* input language code to internal one */
4042 /* and get the first part of the command */
4045 if (!next_token(&ptr,tok,NULL)) continue;
4048 if ((i = process_tok(tok)) >= 0)
4049 commands[i].fn(InBuffer,OutBuffer);
4051 DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
4053 DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
4055 else while (!feof(stdin))
4060 bzero(OutBuffer,smb_size);
4062 /* display a prompt */
4063 DEBUG(1,("smb: %s> ", CNV_LANG(cur_dir)));
4067 line[0] = wait_keyboard(InBuffer);
4068 /* this might not be such a good idea... */
4069 if ( line[0] == EOF)
4072 wait_keyboard(InBuffer);
4075 /* and get a response */
4077 fgets( &line[1],999, stdin);
4079 if (!fgets(line,1000,stdin))
4083 /* input language code to internal one */
4086 /* special case - first char is ! */
4093 /* and get the first part of the command */
4096 if (!next_token(&ptr,tok,NULL)) continue;
4099 if ((i = process_tok(tok)) >= 0)
4100 commands[i].fn(InBuffer,OutBuffer);
4102 DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
4104 DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
4112 /****************************************************************************
4113 usage on the program
4114 ****************************************************************************/
4115 static void usage(char *pname)
4117 DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
4121 DEBUG(0,("[-t termcode] "));
4124 DEBUG(0,("\nVersion %s\n",VERSION));
4125 DEBUG(0,("\t-p port listen on the specified port\n"));
4126 DEBUG(0,("\t-d debuglevel set the debuglevel\n"));
4127 DEBUG(0,("\t-l log basename. Basename for log/debug files\n"));
4128 DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n"));
4129 DEBUG(0,("\t-N don't ask for a password\n"));
4130 DEBUG(0,("\t-P connect to service as a printer\n"));
4131 DEBUG(0,("\t-M host send a winpopup message to the host\n"));
4132 DEBUG(0,("\t-m max protocol set the max protocol level\n"));
4133 DEBUG(0,("\t-L host get a list of shares available on a host\n"));
4134 DEBUG(0,("\t-I dest IP use this IP to connect to\n"));
4135 DEBUG(0,("\t-E write messages to stderr instead of stdout\n"));
4136 DEBUG(0,("\t-U username set the network username\n"));
4137 DEBUG(0,("\t-W workgroup set the workgroup name\n"));
4138 DEBUG(0,("\t-c command string execute semicolon separated commands\n"));
4140 DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
4142 DEBUG(0,("\t-T<c|x>IXgbNa command line tar\n"));
4143 DEBUG(0,("\t-D directory start from directory\n"));
4149 /****************************************************************************
4151 ****************************************************************************/
4152 int main(int argc,char *argv[])
4154 fstring base_directory;
4155 char *pname = argv[0];
4156 int port = SMB_PORT;
4159 extern char *optarg;
4162 BOOL message = False;
4163 extern char tar_type;
4166 *base_directory = 0;
4170 setup_logging(pname,True);
4173 charset_initialise();
4184 strcpy(username,getenv("USER"));
4188 if (*username == 0 && getenv("LOGNAME"))
4190 strcpy(username,getenv("LOGNAME"));
4200 if (*argv[1] != '-')
4203 strcpy(service,argv[1]);
4207 if (count_chars(service,'\\') < 3)
4210 printf("\n%s: Not enough '\\' characters in service\n",service);
4215 if (count_chars(service,'\\') > 3)
4218 printf("\n%s: Too many '\\' characters in service\n",service);
4223 if (argc > 1 && (*argv[1] != '-'))
4226 strcpy(password,argv[1]);
4227 memset(argv[1],'X',strlen(argv[1]));
4234 setup_term_code (KANJI);
4237 getopt(argc, argv,"B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
4241 max_protocol = interpret_protocol(optarg,max_protocol);
4244 strcpy(user_socket_options,optarg);
4248 strcpy(desthost,optarg);
4253 iface_set_default(NULL,optarg,NULL);
4256 strcpy(base_directory,optarg);
4259 if (!tar_parseargs(argc, argv, optarg, optind)) {
4265 strcpy(scope,optarg);
4269 strcpy(query_host,optarg);
4274 strcpy(username,optarg);
4275 if ((p=strchr(username,'%')))
4278 strcpy(password,p+1);
4280 memset(strchr(optarg,'%')+1,'X',strlen(password));
4286 strcpy(workgroup,optarg);
4293 dest_ip = *interpret_addr2(optarg);
4294 if (zero_ip(dest_ip)) exit(1);
4299 strcpy(myname,optarg);
4305 connect_as_printer = True;
4311 DEBUGLEVEL = atoi(optarg);
4314 sprintf(debugf,"%s.client",optarg);
4317 port = atoi(optarg);
4329 if (!setup_term_code (optarg)) {
4330 DEBUG(0, ("%s: unknown terminal code name\n", optarg));
4341 if (!tar_type && !*query_host && !*service && !message)
4348 DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
4351 get_myname(*myname?NULL:myname,NULL);
4357 if (open_sockets(port)) {
4358 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4359 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4362 if ((InBuffer == NULL) || (OutBuffer == NULL))
4365 bzero(OutBuffer,smb_size);
4366 if (!send_login(InBuffer,OutBuffer,True,True))
4369 if (*base_directory) do_cd(base_directory);
4371 ret=process_tar(InBuffer, OutBuffer);
4383 sprintf(service,"\\\\%s\\IPC$",query_host);
4385 connect_as_ipc = True;
4386 if (open_sockets(port))
4391 if (!send_login(NULL,NULL,True,True))
4395 if (!browse_host(True)) {
4399 if (!list_servers(workgroup)) {
4401 list_servers(workgroup);
4414 if (open_sockets(port))
4416 pstring inbuf,outbuf;
4417 bzero(outbuf,smb_size);
4418 if (!send_session_request(inbuf,outbuf))
4421 send_message(inbuf,outbuf);
4429 if (open_sockets(port))
4431 if (!process(base_directory))
4445 /* error code stuff - put together by Merik Karman
4446 merik@blackadder.dsh.oz.au */
4455 /* Dos Error Messages */
4456 err_code_struct dos_msgs[] = {
4457 {"ERRbadfunc",1,"Invalid function."},
4458 {"ERRbadfile",2,"File not found."},
4459 {"ERRbadpath",3,"Directory invalid."},
4460 {"ERRnofids",4,"No file descriptors available"},
4461 {"ERRnoaccess",5,"Access denied."},
4462 {"ERRbadfid",6,"Invalid file handle."},
4463 {"ERRbadmcb",7,"Memory control blocks destroyed."},
4464 {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
4465 {"ERRbadmem",9,"Invalid memory block address."},
4466 {"ERRbadenv",10,"Invalid environment."},
4467 {"ERRbadformat",11,"Invalid format."},
4468 {"ERRbadaccess",12,"Invalid open mode."},
4469 {"ERRbaddata",13,"Invalid data."},
4470 {"ERR",14,"reserved."},
4471 {"ERRbaddrive",15,"Invalid drive specified."},
4472 {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
4473 {"ERRdiffdevice",17,"Not same device."},
4474 {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
4475 {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
4476 {"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."},
4477 {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
4478 {"ERRbadpipe",230,"Pipe invalid."},
4479 {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
4480 {"ERRpipeclosing",232,"Pipe close in progress."},
4481 {"ERRnotconnected",233,"No process on other end of pipe."},
4482 {"ERRmoredata",234,"There is more data to be returned."},
4483 {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
4486 /* Server Error Messages */
4487 err_code_struct server_msgs[] = {
4488 {"ERRerror",1,"Non-specific error code."},
4489 {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
4490 {"ERRbadtype",3,"reserved."},
4491 {"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."},
4492 {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
4493 {"ERRinvnetname",6,"Invalid network name in tree connect."},
4494 {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."},
4495 {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
4496 {"ERRqtoobig",50,"Print queue full -- no space."},
4497 {"ERRqeof",51,"EOF on print queue dump."},
4498 {"ERRinvpfid",52,"Invalid print file FID."},
4499 {"ERRsmbcmd",64,"The server did not recognize the command received."},
4500 {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
4501 {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."},
4502 {"ERRreserved",68,"reserved."},
4503 {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."},
4504 {"ERRreserved",70,"reserved."},
4505 {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
4506 {"ERRpaused",81,"Server is paused."},
4507 {"ERRmsgoff",82,"Not receiving messages."},
4508 {"ERRnoroom",83,"No room to buffer message."},
4509 {"ERRrmuns",87,"Too many remote user names."},
4510 {"ERRtimeout",88,"Operation timed out."},
4511 {"ERRnoresource",89,"No resources currently available for request."},
4512 {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
4513 {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
4514 {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
4515 {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
4516 {"ERRcontmpx",252,"Continue in MPX mode."},
4517 {"ERRreserved",253,"reserved."},
4518 {"ERRreserved",254,"reserved."},
4519 {"ERRnosupport",0xFFFF,"Function not supported."},
4522 /* Hard Error Messages */
4523 err_code_struct hard_msgs[] = {
4524 {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
4525 {"ERRbadunit",20,"Unknown unit."},
4526 {"ERRnotready",21,"Drive not ready."},
4527 {"ERRbadcmd",22,"Unknown command."},
4528 {"ERRdata",23,"Data error (CRC)."},
4529 {"ERRbadreq",24,"Bad request structure length."},
4530 {"ERRseek",25 ,"Seek error."},
4531 {"ERRbadmedia",26,"Unknown media type."},
4532 {"ERRbadsector",27,"Sector not found."},
4533 {"ERRnopaper",28,"Printer out of paper."},
4534 {"ERRwrite",29,"Write fault."},
4535 {"ERRread",30,"Read fault."},
4536 {"ERRgeneral",31,"General failure."},
4537 {"ERRbadshare",32,"A open conflicts with an existing open."},
4538 {"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."},
4539 {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
4540 {"ERRFCBUnavail",35,"No FCBs are available to process request."},
4541 {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
4549 err_code_struct *err_msgs;
4552 {0x01,"ERRDOS",dos_msgs},
4553 {0x02,"ERRSRV",server_msgs},
4554 {0x03,"ERRHRD",hard_msgs},
4555 {0x04,"ERRXOS",NULL},
4556 {0xE1,"ERRRMX1",NULL},
4557 {0xE2,"ERRRMX2",NULL},
4558 {0xE3,"ERRRMX3",NULL},
4559 {0xFF,"ERRCMD",NULL},
4563 /****************************************************************************
4564 return a SMB error string from a SMB buffer
4565 ****************************************************************************/
4566 char *smb_errstr(char *inbuf)
4569 int class = CVAL(inbuf,smb_rcls);
4570 int num = SVAL(inbuf,smb_err);
4573 for (i=0;err_classes[i].class;i++)
4574 if (err_classes[i].code == class)
4576 if (err_classes[i].err_msgs)
4578 err_code_struct *err = err_classes[i].err_msgs;
4579 for (j=0;err[j].name;j++)
4580 if (num == err[j].code)
4583 sprintf(ret,"%s - %s (%s)",err_classes[i].class,
4584 err[j].name,err[j].message);
4586 sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
4591 sprintf(ret,"%s - %d",err_classes[i].class,num);
4595 sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);