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"));
2878 /****************************************************************************
2879 send a login command
2880 ****************************************************************************/
2881 static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
2883 BOOL was_null = (!inbuf && !outbuf);
2885 time_t servertime = 0;
2886 extern int serverzone;
2896 {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
2897 {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
2898 {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
2899 {PROTOCOL_LANMAN1,"LANMAN1.0"},
2900 {PROTOCOL_LANMAN2,"LM1.2X002"},
2901 {PROTOCOL_LANMAN2,"Samba"},
2902 {PROTOCOL_NT1,"NT LM 0.12"},
2903 {PROTOCOL_NT1,"NT LANMAN 1.0"},
2913 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2914 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
2918 if (strstr(service,"IPC$")) connect_as_ipc = True;
2922 if (connect_as_printer)
2923 strcpy(dev,"LPT1:");
2928 if (start_session && !send_session_request(inbuf,outbuf))
2938 bzero(outbuf,smb_size);
2940 /* setup the protocol strings */
2944 for (plength=0,numprots=0;
2945 prots[numprots].name && prots[numprots].prot<=max_protocol;
2947 plength += strlen(prots[numprots].name)+2;
2949 set_message(outbuf,0,plength,True);
2951 p = smb_buf(outbuf);
2953 prots[numprots].name && prots[numprots].prot<=max_protocol;
2957 strcpy(p,prots[numprots].name);
2962 CVAL(outbuf,smb_com) = SMBnegprot;
2965 CVAL(smb_buf(outbuf),0) = 2;
2967 send_smb(Client,outbuf);
2968 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
2972 if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
2974 DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
2975 myname,desthost,smb_errstr(inbuf)));
2984 Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
2987 if (Protocol < PROTOCOL_NT1) {
2988 sec_mode = SVAL(inbuf,smb_vwv1);
2989 max_xmit = SVAL(inbuf,smb_vwv2);
2990 sesskey = IVAL(inbuf,smb_vwv6);
2991 serverzone = SVALS(inbuf,smb_vwv10)*60;
2992 /* this time is converted to GMT by make_unix_date */
2993 servertime = make_unix_date(inbuf+smb_vwv8);
2994 if (Protocol >= PROTOCOL_COREPLUS) {
2995 readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
2996 writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
2998 crypt_len = smb_buflen(inbuf);
2999 memcpy(cryptkey,smb_buf(inbuf),8);
3000 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
3001 max_vcs = SVAL(inbuf,smb_vwv4);
3002 DEBUG(3,("max vcs %d\n",max_vcs));
3003 DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
3006 sec_mode = CVAL(inbuf,smb_vwv1);
3007 max_xmit = IVAL(inbuf,smb_vwv3+1);
3008 sesskey = IVAL(inbuf,smb_vwv7+1);
3009 serverzone = SVALS(inbuf,smb_vwv15+1)*60;
3010 /* this time arrives in real GMT */
3011 servertime = interpret_long_date(inbuf+smb_vwv11+1);
3012 crypt_len = CVAL(inbuf,smb_vwv16+1);
3013 memcpy(cryptkey,smb_buf(inbuf),8);
3014 if (IVAL(inbuf,smb_vwv9+1) & 1)
3015 readbraw_supported = writebraw_supported = True;
3016 DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
3017 max_vcs = SVAL(inbuf,smb_vwv2+1);
3018 DEBUG(3,("max vcs %d\n",max_vcs));
3019 DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
3020 DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
3023 DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
3024 DEBUG(3,("max xmt %d\n",max_xmit));
3025 DEBUG(3,("Got %d byte crypt key\n",crypt_len));
3026 DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
3028 doencrypt = ((sec_mode & 2) != 0);
3031 static BOOL done_time = False;
3033 DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
3034 asctime(LocalTime(&servertime)),
3035 -(double)(serverzone/3600.0)));
3045 pass = (char *)getpass("Password: ");
3047 if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
3050 int passlen = strlen(pass)+1;
3054 if (doencrypt && *pass) {
3055 DEBUG(3,("Using encrypted passwords\n"));
3057 SMBencrypt(pass,cryptkey,pword);
3063 /* if in share level security then don't send a password now */
3064 if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;}
3066 /* send a session setup command */
3067 bzero(outbuf,smb_size);
3069 if (Protocol < PROTOCOL_NT1) {
3070 set_message(outbuf,10,1 + strlen(username) + passlen,True);
3071 CVAL(outbuf,smb_com) = SMBsesssetupX;
3074 CVAL(outbuf,smb_vwv0) = 0xFF;
3075 SSVAL(outbuf,smb_vwv2,max_xmit);
3076 SSVAL(outbuf,smb_vwv3,2);
3077 SSVAL(outbuf,smb_vwv4,max_vcs-1);
3078 SIVAL(outbuf,smb_vwv5,sesskey);
3079 SSVAL(outbuf,smb_vwv7,passlen);
3080 p = smb_buf(outbuf);
3081 memcpy(p,pword,passlen);
3085 if (!doencrypt) passlen--;
3087 set_message(outbuf,13,0,True);
3088 CVAL(outbuf,smb_com) = SMBsesssetupX;
3091 CVAL(outbuf,smb_vwv0) = 0xFF;
3092 SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
3093 SSVAL(outbuf,smb_vwv3,2);
3094 SSVAL(outbuf,smb_vwv4,getpid());
3095 SIVAL(outbuf,smb_vwv5,sesskey);
3096 SSVAL(outbuf,smb_vwv7,passlen);
3097 SSVAL(outbuf,smb_vwv8,0);
3098 p = smb_buf(outbuf);
3099 memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
3100 strcpy(p,username);p = skip_string(p,1);
3101 strcpy(p,workgroup);p = skip_string(p,1);
3102 strcpy(p,"Unix");p = skip_string(p,1);
3103 strcpy(p,"Samba");p = skip_string(p,1);
3104 set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
3107 send_smb(Client,outbuf);
3108 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
3112 if (CVAL(inbuf,smb_rcls) != 0)
3115 ((CVAL(inbuf,smb_rcls) == ERRDOS &&
3116 SVAL(inbuf,smb_err) == ERRnoaccess) ||
3117 (CVAL(inbuf,smb_rcls) == ERRSRV &&
3118 SVAL(inbuf,smb_err) == ERRbadpw)))
3121 DEBUG(3,("resending login\n"));
3125 DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
3126 username,myname,desthost,smb_errstr(inbuf)));
3127 DEBUG(0,("You might find the -U, -W or -n options useful\n"));
3128 DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
3129 DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
3138 if (Protocol >= PROTOCOL_NT1) {
3139 char *domain,*os,*lanman;
3142 lanman = skip_string(os,1);
3143 domain = skip_string(lanman,1);
3144 if (*domain || *os || *lanman)
3145 DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
3148 /* use the returned uid from now on */
3149 if (SVAL(inbuf,smb_uid) != uid)
3150 DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
3151 SVAL(inbuf,smb_uid),uid));
3152 uid = SVAL(inbuf,smb_uid);
3155 /* now we've got a connection - send a tcon message */
3156 bzero(outbuf,smb_size);
3158 if (strncmp(service,"\\\\",2) != 0)
3160 DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
3161 DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
3168 int passlen = strlen(pass)+1;
3173 if (doencrypt && *pass) {
3175 SMBencrypt(pass,cryptkey,pword);
3179 /* if in user level security then don't send a password now */
3180 if ((sec_mode & 1)) {
3181 strcpy(pword, ""); passlen=1;
3184 if (Protocol <= PROTOCOL_CORE) {
3185 set_message(outbuf,0,6 + strlen(service) + passlen + strlen(dev),True);
3186 CVAL(outbuf,smb_com) = SMBtcon;
3189 p = smb_buf(outbuf);
3192 p = skip_string(p,1);
3194 memcpy(p,pword,passlen);
3200 set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
3201 CVAL(outbuf,smb_com) = SMBtconX;
3204 SSVAL(outbuf,smb_vwv0,0xFF);
3205 SSVAL(outbuf,smb_vwv3,passlen);
3207 p = smb_buf(outbuf);
3208 memcpy(p,pword,passlen);
3211 p = skip_string(p,1);
3216 send_smb(Client,outbuf);
3217 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
3219 /* trying again with a blank password */
3220 if (CVAL(inbuf,smb_rcls) != 0 &&
3221 (int)strlen(pass) > 0 &&
3223 Protocol >= PROTOCOL_LANMAN1)
3225 DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
3230 if (CVAL(inbuf,smb_rcls) != 0)
3232 DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
3233 DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
3234 DEBUG(0,("Some servers insist that these be in uppercase\n"));
3244 if (Protocol <= PROTOCOL_CORE) {
3245 max_xmit = SVAL(inbuf,smb_vwv0);
3247 cnum = SVAL(inbuf,smb_vwv1);
3250 max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
3252 max_xmit = BUFFER_SIZE - 4;
3254 cnum = SVAL(inbuf,smb_tid);
3257 DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
3268 /****************************************************************************
3269 send a logout command
3270 ****************************************************************************/
3271 static void send_logout(void )
3273 pstring inbuf,outbuf;
3275 bzero(outbuf,smb_size);
3276 set_message(outbuf,0,0,True);
3277 CVAL(outbuf,smb_com) = SMBtdis;
3278 SSVAL(outbuf,smb_tid,cnum);
3281 send_smb(Client,outbuf);
3282 receive_smb(Client,inbuf,SHORT_TIMEOUT);
3284 if (CVAL(inbuf,smb_rcls) != 0)
3286 DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
3298 /****************************************************************************
3300 ****************************************************************************/
3301 static BOOL call_api(int prcnt,int drcnt,
3302 int mprcnt,int mdrcnt,
3303 int *rprcnt,int *rdrcnt,
3304 char *param,char *data,
3305 char **rparam,char **rdata)
3307 static char *inbuf=NULL;
3308 static char *outbuf=NULL;
3310 if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3311 if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
3313 send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0,
3318 return (receive_trans_response(inbuf,SMBtrans,
3323 /****************************************************************************
3324 send a SMB trans or trans2 request
3325 ****************************************************************************/
3326 static BOOL send_trans_request(char *outbuf,int trans,
3327 char *name,int fid,int flags,
3328 char *data,char *param,uint16 *setup,
3329 int ldata,int lparam,int lsetup,
3330 int mdata,int mparam,int msetup)
3333 int this_ldata,this_lparam;
3334 int tot_data=0,tot_param=0;
3335 char *outdata,*outparam;
3339 this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
3340 this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
3342 bzero(outbuf,smb_size);
3343 set_message(outbuf,14+lsetup,0,True);
3344 CVAL(outbuf,smb_com) = trans;
3345 SSVAL(outbuf,smb_tid,cnum);
3348 outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
3349 outdata = outparam+this_lparam;
3351 /* primary request */
3352 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
3353 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
3354 SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
3355 SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
3356 SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
3357 SSVAL(outbuf,smb_flags,flags); /* flags */
3358 SIVAL(outbuf,smb_timeout,0); /* timeout */
3359 SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
3360 SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
3361 SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
3362 SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
3363 SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
3364 for (i=0;i<lsetup;i++) /* setup[] */
3365 SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
3366 p = smb_buf(outbuf);
3367 if (trans==SMBtrans)
3368 strcpy(p,name); /* name[] */
3371 *p++ = 0; /* put in a null smb_name */
3372 *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
3374 if (this_lparam) /* param[] */
3375 memcpy(outparam,param,this_lparam);
3376 if (this_ldata) /* data[] */
3377 memcpy(outdata,data,this_ldata);
3378 set_message(outbuf,14+lsetup, /* wcnt, bcc */
3379 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
3382 send_smb(Client,outbuf);
3384 if (this_ldata < ldata || this_lparam < lparam)
3386 /* receive interim response */
3387 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
3389 DEBUG(0,("%s request failed (%s)\n",
3390 trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
3394 tot_data = this_ldata;
3395 tot_param = this_lparam;
3397 while (tot_data < ldata || tot_param < lparam)
3399 this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
3400 this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
3402 set_message(outbuf,trans==SMBtrans?8:9,0,True);
3403 CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
3405 outparam = smb_buf(outbuf);
3406 outdata = outparam+this_lparam;
3408 /* secondary request */
3409 SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
3410 SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
3411 SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
3412 SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
3413 SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
3414 SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
3415 SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
3416 SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
3417 if (trans==SMBtrans2)
3418 SSVAL(outbuf,smb_sfid,fid); /* fid */
3419 if (this_lparam) /* param[] */
3420 memcpy(outparam,param,this_lparam);
3421 if (this_ldata) /* data[] */
3422 memcpy(outdata,data,this_ldata);
3423 set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
3424 PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
3427 send_smb(Client,outbuf);
3429 tot_data += this_ldata;
3430 tot_param += this_lparam;
3437 /****************************************************************************
3438 try and browse available connections on a host
3439 ****************************************************************************/
3440 static BOOL browse_host(BOOL sort)
3443 #define strcasecmp StrCaseCmp
3445 extern int strcasecmp();
3447 char *rparam = NULL;
3454 /* now send a SMBtrans command with api RNetShareEnum */
3456 SSVAL(p,0,0); /* api number */
3459 p = skip_string(p,1);
3461 p = skip_string(p,1);
3463 SSVAL(p,2,BUFFER_SIZE);
3466 if (call_api(PTR_DIFF(p,param),0,
3472 int res = SVAL(rparam,0);
3473 int converter=SVAL(rparam,2);
3475 BOOL long_share_name=False;
3479 count=SVAL(rparam,4);
3484 printf("\n\tSharename Type Comment\n");
3485 printf("\t--------- ---- -------\n");
3489 qsort(p,count,20,QSORT_CAST strcasecmp);
3491 for (i=0;i<count;i++)
3494 int type = SVAL(p,14);
3495 int comment_offset = IVAL(p,16) & 0xFFFF;
3501 case STYPE_DISKTREE:
3502 strcpy(typestr,"Disk"); break;
3504 strcpy(typestr,"Printer"); break;
3506 strcpy(typestr,"Device"); break;
3508 strcpy(typestr,"IPC"); break;
3511 printf("\t%-15.15s%-10.10s%s\n",
3514 comment_offset?rdata+comment_offset-converter:"");
3516 if (strlen(sname)>8) long_share_name=True;
3521 if (long_share_name) {
3522 printf("\nNOTE: There were share names longer than 8 chars.\nOn older clients these may not be accessible or may give browsing errors\n");
3527 if (rparam) free(rparam);
3528 if (rdata) free(rdata);
3534 /****************************************************************************
3535 get some server info
3536 ****************************************************************************/
3537 static void server_info()
3539 char *rparam = NULL;
3545 bzero(param,sizeof(param));
3548 SSVAL(p,0,63); /* api number */
3551 p = skip_string(p,1);
3552 strcpy(p,"zzzBBzz");
3553 p = skip_string(p,1);
3554 SSVAL(p,0,10); /* level 10 */
3558 if (call_api(PTR_DIFF(p,param),0,
3564 int res = SVAL(rparam,0);
3565 int converter=SVAL(rparam,2);
3571 printf("\nServer=[%s] User=[%s] Workgroup=[%s] Domain=[%s]\n",
3572 rdata+SVAL(p,0)-converter,
3573 rdata+SVAL(p,4)-converter,
3574 rdata+SVAL(p,8)-converter,
3575 rdata+SVAL(p,14)-converter);
3579 if (rparam) free(rparam);
3580 if (rdata) free(rdata);
3586 /****************************************************************************
3587 try and browse available connections on a host
3588 ****************************************************************************/
3589 static BOOL list_servers()
3591 char *rparam = NULL;
3600 /* now send a SMBtrans command with api ServerEnum? */
3602 SSVAL(p,0,0x68); /* api number */
3604 strcpy(p,"WrLehDO");
3605 p = skip_string(p,1);
3607 strcpy(p,"B16BBDz");
3609 strcpy(p,getenv("XX_STR2"));
3612 p = skip_string(p,1);
3614 SSVAL(p,2,0x2000); /* buf length */
3617 SIVAL(p,0,SV_TYPE_ALL);
3619 if (call_api(PTR_DIFF(p+4,param),0,
3625 int res = SVAL(rparam,0);
3626 int converter=SVAL(rparam,2);
3631 count=SVAL(rparam,4);
3634 printf("\n\nThis machine has a browse list:\n");
3635 printf("\n\tServer Comment\n");
3636 printf("\t--------- -------\n");
3639 for (i=0;i<count;i++) {
3641 int comment_offset = IVAL(p2,22) & 0xFFFF;
3642 printf("\t%-16.16s %s\n",
3644 comment_offset?rdata+comment_offset-converter:"");
3652 if (rparam) {free(rparam); rparam = NULL;}
3653 if (rdata) {free(rdata); rdata = NULL;}
3655 SIVAL(p,0,SV_TYPE_DOMAIN_ENUM);
3657 if (call_api(PTR_DIFF(p+4,param),0,
3663 int res = SVAL(rparam,0);
3664 int converter=SVAL(rparam,2);
3669 count=SVAL(rparam,4);
3672 printf("\n\nThis machine has a workgroup list:\n");
3673 printf("\n\tWorkgroup Master\n");
3674 printf("\t--------- -------\n");
3677 for (i=0;i<count;i++) {
3679 int comment_offset = IVAL(p2,22) & 0xFFFF;
3680 printf("\t%-16.16s %s\n",
3682 comment_offset?rdata+comment_offset-converter:"");
3690 if (rparam) free(rparam);
3691 if (rdata) free(rdata);
3697 /* This defines the commands supported by this client */
3705 {"ls",cmd_dir,"<mask> list the contents of the current directory"},
3706 {"dir",cmd_dir,"<mask> list the contents of the current directory"},
3707 {"lcd",cmd_lcd,"[directory] change/report the local current working directory"},
3708 {"cd",cmd_cd,"[directory] change/report the remote directory"},
3709 {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)"},
3710 {"get",cmd_get,"<remote name> [local name] get a file"},
3711 {"mget",cmd_mget,"<mask> get all the matching files"},
3712 {"put",cmd_put,"<local name> [remote name] put a file"},
3713 {"mput",cmd_mput,"<mask> put all matching files"},
3714 {"rename",cmd_rename,"<src> <dest> rename some files"},
3715 {"more",cmd_more,"<remote name> view a remote file with your pager"},
3716 {"mask",cmd_select,"<mask> mask all filenames against this"},
3717 {"del",cmd_del,"<mask> delete all matching files"},
3718 {"rm",cmd_del,"<mask> delete all matching files"},
3719 {"mkdir",cmd_mkdir,"<directory> make a directory"},
3720 {"md",cmd_mkdir,"<directory> make a directory"},
3721 {"rmdir",cmd_rmdir,"<directory> remove a directory"},
3722 {"rd",cmd_rmdir,"<directory> remove a directory"},
3723 {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput"},
3724 {"recurse",cmd_recurse,"toggle directory recursion for mget and mput"},
3725 {"translate",cmd_translate,"toggle text translation for printing"},
3726 {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get"},
3727 {"print",cmd_print,"<file name> print a file"},
3728 {"printmode",cmd_printmode,"<graphics or text> set the print mode"},
3729 {"queue",cmd_queue,"show the print queue"},
3730 {"cancel",cmd_cancel,"<jobid> cancel a print queue entry"},
3731 {"stat",cmd_stat,"<file> get info on a file (experimental!)"},
3732 {"quit",send_logout,"logoff the server"},
3733 {"q",send_logout,"logoff the server"},
3734 {"exit",send_logout,"logoff the server"},
3735 {"newer",cmd_newer,"<file> only mget files newer than the specified local file"},
3736 {"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"},
3737 {"tar",cmd_tar,"tar <c|x>[IXbgNa] current directory to/from <file name>" },
3738 {"blocksize",cmd_block,"blocksize <number> (default 20)" },
3739 {"tarmode",cmd_tarmode,
3740 "<full|inc|reset|noreset> tar's behaviour towards archive bits" },
3741 {"setmode",cmd_setmode,"filename <setmode string> change modes of file"},
3742 {"help",cmd_help,"[command] give help on a command"},
3743 {"?",cmd_help,"[command] give help on a command"},
3744 {"!",NULL,"run a shell command on the local system"},
3749 /*******************************************************************
3750 lookup a command string in the list of commands, including
3752 ******************************************************************/
3753 static int process_tok(fstring tok)
3755 int i = 0, matches = 0;
3757 int tok_len = strlen(tok);
3759 while (commands[i].fn != NULL)
3761 if (strequal(commands[i].name,tok))
3767 else if (strnequal(commands[i].name, tok, tok_len+1))
3777 else if (matches == 1)
3783 /****************************************************************************
3785 ****************************************************************************/
3791 if (next_token(NULL,buf,NULL))
3793 if ((i = process_tok(buf)) >= 0)
3794 DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));
3797 while (commands[i].description)
3799 for (j=0; commands[i].description && (j<5); j++) {
3800 DEBUG(0,("%-15s",commands[i].name));
3807 /****************************************************************************
3808 open the client sockets
3809 ****************************************************************************/
3810 static BOOL open_sockets(int port )
3812 static int last_port;
3820 if (port == 0) port=last_port;
3831 strcpy(service2,service);
3832 host = strtok(service2,"\\/");
3834 DEBUG(0,("Badly formed host name\n"));
3837 strcpy(desthost,host);
3842 get_myname(myname,NULL);
3846 DEBUG(3,("Opening sockets\n"));
3852 if ((hp = Get_Hostbyname(host))) {
3853 putip((char *)&dest_ip,(char *)hp->h_addr);
3857 /* Try and resolve the name with the netbios server */
3860 if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) {
3861 set_socket_options(bcast, "SO_BROADCAST");
3863 if (name_query(bcast, host, 0x20, True, True, *iface_bcast(dest_ip),
3871 DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
3877 Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
3881 DEBUG(3,("Connected\n"));
3883 set_socket_options(Client,user_socket_options);
3888 /****************************************************************************
3889 wait for keyboard activity, swallowing network packets
3890 ****************************************************************************/
3892 static char wait_keyboard(char *buffer)
3894 static void wait_keyboard(char *buffer)
3899 struct timeval timeout;
3909 FD_SET(Client,&fds);
3911 FD_SET(fileno(stdin),&fds);
3914 timeout.tv_sec = 20;
3915 timeout.tv_usec = 0;
3919 selrtn = sys_select(&fds,&timeout);
3922 if (FD_ISSET(fileno(stdin),&fds))
3930 f_flags = fcntl(fileno(stdin), F_GETFL, 0);
3931 fcntl( fileno(stdin), F_SETFL, f_flags | O_NONBLOCK);
3932 readret = read_data( fileno(stdin), &ch, 1);
3933 fcntl(fileno(stdin), F_SETFL, f_flags);
3936 if (errno != EAGAIN)
3938 /* should crash here */
3939 DEBUG(1,("readchar stdin failed\n"));
3942 else if (readret != 0)
3948 if (FD_ISSET(Client,&fds))
3949 receive_smb(Client,buffer,0);
3956 chkpath("\\",False);
3959 chkpath("\\",False);
3965 /****************************************************************************
3966 close and open the connection again
3967 ****************************************************************************/
3968 BOOL reopen_connection(char *inbuf,char *outbuf)
3970 static int open_count=0;
3974 if (open_count>5) return(False);
3976 DEBUG(1,("Trying to re-open connection\n"));
3978 set_message(outbuf,0,0,True);
3979 SCVAL(outbuf,smb_com,SMBtdis);
3980 SSVAL(outbuf,smb_tid,cnum);
3983 send_smb(Client,outbuf);
3984 receive_smb(Client,inbuf,SHORT_TIMEOUT);
3987 if (!open_sockets(0)) return(False);
3989 return(send_login(inbuf,outbuf,True,True));
3992 /****************************************************************************
3993 process commands from the client
3994 ****************************************************************************/
3995 static BOOL process(char *base_directory)
4001 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4002 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4004 if ((InBuffer == NULL) || (OutBuffer == NULL))
4007 bzero(OutBuffer,smb_size);
4009 if (!send_login(InBuffer,OutBuffer,True,True))
4012 if (*base_directory) do_cd(base_directory);
4015 if (cmd[0] != '\0') while (cmd[0] != '\0')
4021 if ((p = strchr(cmd, ';')) == 0)
4023 strncpy(line, cmd, 999);
4029 if (p - cmd > 999) p = cmd + 999;
4030 strncpy(line, cmd, p - cmd);
4031 line[p - cmd] = '\0';
4035 /* input language code to internal one */
4038 /* and get the first part of the command */
4041 if (!next_token(&ptr,tok,NULL)) continue;
4044 if ((i = process_tok(tok)) >= 0)
4045 commands[i].fn(InBuffer,OutBuffer);
4047 DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
4049 DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
4051 else while (!feof(stdin))
4056 bzero(OutBuffer,smb_size);
4058 /* display a prompt */
4059 DEBUG(1,("smb: %s> ", CNV_LANG(cur_dir)));
4063 line[0] = wait_keyboard(InBuffer);
4064 /* this might not be such a good idea... */
4065 if ( line[0] == EOF)
4068 wait_keyboard(InBuffer);
4071 /* and get a response */
4073 fgets( &line[1],999, stdin);
4075 if (!fgets(line,1000,stdin))
4079 /* input language code to internal one */
4082 /* special case - first char is ! */
4089 /* and get the first part of the command */
4092 if (!next_token(&ptr,tok,NULL)) continue;
4095 if ((i = process_tok(tok)) >= 0)
4096 commands[i].fn(InBuffer,OutBuffer);
4098 DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
4100 DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
4108 /****************************************************************************
4109 usage on the program
4110 ****************************************************************************/
4111 static void usage(char *pname)
4113 DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
4117 DEBUG(0,("[-t termcode] "));
4120 DEBUG(0,("\nVersion %s\n",VERSION));
4121 DEBUG(0,("\t-p port listen on the specified port\n"));
4122 DEBUG(0,("\t-d debuglevel set the debuglevel\n"));
4123 DEBUG(0,("\t-l log basename. Basename for log/debug files\n"));
4124 DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n"));
4125 DEBUG(0,("\t-N don't ask for a password\n"));
4126 DEBUG(0,("\t-P connect to service as a printer\n"));
4127 DEBUG(0,("\t-M host send a winpopup message to the host\n"));
4128 DEBUG(0,("\t-m max protocol set the max protocol level\n"));
4129 DEBUG(0,("\t-L host get a list of shares available on a host\n"));
4130 DEBUG(0,("\t-I dest IP use this IP to connect to\n"));
4131 DEBUG(0,("\t-E write messages to stderr instead of stdout\n"));
4132 DEBUG(0,("\t-U username set the network username\n"));
4133 DEBUG(0,("\t-W workgroup set the workgroup name\n"));
4134 DEBUG(0,("\t-c command string execute semicolon separated commands\n"));
4136 DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
4138 DEBUG(0,("\t-T<c|x>IXgbNa command line tar\n"));
4139 DEBUG(0,("\t-D directory start from directory\n"));
4145 /****************************************************************************
4147 ****************************************************************************/
4148 int main(int argc,char *argv[])
4150 fstring base_directory;
4151 char *pname = argv[0];
4152 int port = SMB_PORT;
4155 extern char *optarg;
4158 BOOL message = False;
4159 extern char tar_type;
4162 *base_directory = 0;
4166 setup_logging(pname,True);
4169 charset_initialise();
4180 strcpy(username,getenv("USER"));
4184 if (*username == 0 && getenv("LOGNAME"))
4186 strcpy(username,getenv("LOGNAME"));
4196 if (*argv[1] != '-')
4199 strcpy(service,argv[1]);
4203 if (count_chars(service,'\\') < 3)
4206 printf("\n%s: Not enough '\\' characters in service\n",service);
4211 if (count_chars(service,'\\') > 3)
4214 printf("\n%s: Too many '\\' characters in service\n",service);
4219 if (argc > 1 && (*argv[1] != '-'))
4222 strcpy(password,argv[1]);
4223 memset(argv[1],'X',strlen(argv[1]));
4230 setup_term_code (KANJI);
4233 getopt(argc, argv,"B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
4237 max_protocol = interpret_protocol(optarg,max_protocol);
4240 strcpy(user_socket_options,optarg);
4244 strcpy(desthost,optarg);
4249 iface_set_default(NULL,optarg,NULL);
4252 strcpy(base_directory,optarg);
4255 if (!tar_parseargs(argc, argv, optarg, optind)) {
4261 strcpy(scope,optarg);
4265 strcpy(query_host,optarg);
4270 strcpy(username,optarg);
4271 if ((p=strchr(username,'%')))
4274 strcpy(password,p+1);
4276 memset(strchr(optarg,'%')+1,'X',strlen(password));
4282 strcpy(workgroup,optarg);
4289 dest_ip = *interpret_addr2(optarg);
4290 if (zero_ip(dest_ip)) exit(1);
4295 strcpy(myname,optarg);
4301 connect_as_printer = True;
4307 DEBUGLEVEL = atoi(optarg);
4310 sprintf(debugf,"%s.client",optarg);
4313 port = atoi(optarg);
4325 if (!setup_term_code (optarg)) {
4326 DEBUG(0, ("%s: unknown terminal code name\n", optarg));
4337 if (!tar_type && !*query_host && !*service && !message)
4344 DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
4347 get_myname(*myname?NULL:myname,NULL);
4353 if (open_sockets(port)) {
4354 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4355 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4358 if ((InBuffer == NULL) || (OutBuffer == NULL))
4361 bzero(OutBuffer,smb_size);
4362 if (!send_login(InBuffer,OutBuffer,True,True))
4365 if (*base_directory) do_cd(base_directory);
4367 ret=process_tar(InBuffer, OutBuffer);
4379 sprintf(service,"\\\\%s\\IPC$",query_host);
4381 connect_as_ipc = True;
4382 if (open_sockets(port))
4387 if (!send_login(NULL,NULL,True,True))
4391 if (!browse_host(True)) {
4395 if (!list_servers()) {
4410 if (open_sockets(port))
4412 pstring inbuf,outbuf;
4413 bzero(outbuf,smb_size);
4414 if (!send_session_request(inbuf,outbuf))
4417 send_message(inbuf,outbuf);
4425 if (open_sockets(port))
4427 if (!process(base_directory))
4441 /* error code stuff - put together by Merik Karman
4442 merik@blackadder.dsh.oz.au */
4451 /* Dos Error Messages */
4452 err_code_struct dos_msgs[] = {
4453 {"ERRbadfunc",1,"Invalid function."},
4454 {"ERRbadfile",2,"File not found."},
4455 {"ERRbadpath",3,"Directory invalid."},
4456 {"ERRnofids",4,"No file descriptors available"},
4457 {"ERRnoaccess",5,"Access denied."},
4458 {"ERRbadfid",6,"Invalid file handle."},
4459 {"ERRbadmcb",7,"Memory control blocks destroyed."},
4460 {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
4461 {"ERRbadmem",9,"Invalid memory block address."},
4462 {"ERRbadenv",10,"Invalid environment."},
4463 {"ERRbadformat",11,"Invalid format."},
4464 {"ERRbadaccess",12,"Invalid open mode."},
4465 {"ERRbaddata",13,"Invalid data."},
4466 {"ERR",14,"reserved."},
4467 {"ERRbaddrive",15,"Invalid drive specified."},
4468 {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
4469 {"ERRdiffdevice",17,"Not same device."},
4470 {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
4471 {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
4472 {"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."},
4473 {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
4474 {"ERRbadpipe",230,"Pipe invalid."},
4475 {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
4476 {"ERRpipeclosing",232,"Pipe close in progress."},
4477 {"ERRnotconnected",233,"No process on other end of pipe."},
4478 {"ERRmoredata",234,"There is more data to be returned."},
4479 {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
4482 /* Server Error Messages */
4483 err_code_struct server_msgs[] = {
4484 {"ERRerror",1,"Non-specific error code."},
4485 {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
4486 {"ERRbadtype",3,"reserved."},
4487 {"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."},
4488 {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
4489 {"ERRinvnetname",6,"Invalid network name in tree connect."},
4490 {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."},
4491 {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
4492 {"ERRqtoobig",50,"Print queue full -- no space."},
4493 {"ERRqeof",51,"EOF on print queue dump."},
4494 {"ERRinvpfid",52,"Invalid print file FID."},
4495 {"ERRsmbcmd",64,"The server did not recognize the command received."},
4496 {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
4497 {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."},
4498 {"ERRreserved",68,"reserved."},
4499 {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."},
4500 {"ERRreserved",70,"reserved."},
4501 {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
4502 {"ERRpaused",81,"Server is paused."},
4503 {"ERRmsgoff",82,"Not receiving messages."},
4504 {"ERRnoroom",83,"No room to buffer message."},
4505 {"ERRrmuns",87,"Too many remote user names."},
4506 {"ERRtimeout",88,"Operation timed out."},
4507 {"ERRnoresource",89,"No resources currently available for request."},
4508 {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
4509 {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
4510 {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
4511 {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
4512 {"ERRcontmpx",252,"Continue in MPX mode."},
4513 {"ERRreserved",253,"reserved."},
4514 {"ERRreserved",254,"reserved."},
4515 {"ERRnosupport",0xFFFF,"Function not supported."},
4518 /* Hard Error Messages */
4519 err_code_struct hard_msgs[] = {
4520 {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
4521 {"ERRbadunit",20,"Unknown unit."},
4522 {"ERRnotready",21,"Drive not ready."},
4523 {"ERRbadcmd",22,"Unknown command."},
4524 {"ERRdata",23,"Data error (CRC)."},
4525 {"ERRbadreq",24,"Bad request structure length."},
4526 {"ERRseek",25 ,"Seek error."},
4527 {"ERRbadmedia",26,"Unknown media type."},
4528 {"ERRbadsector",27,"Sector not found."},
4529 {"ERRnopaper",28,"Printer out of paper."},
4530 {"ERRwrite",29,"Write fault."},
4531 {"ERRread",30,"Read fault."},
4532 {"ERRgeneral",31,"General failure."},
4533 {"ERRbadshare",32,"A open conflicts with an existing open."},
4534 {"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."},
4535 {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
4536 {"ERRFCBUnavail",35,"No FCBs are available to process request."},
4537 {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
4545 err_code_struct *err_msgs;
4548 {0x01,"ERRDOS",dos_msgs},
4549 {0x02,"ERRSRV",server_msgs},
4550 {0x03,"ERRHRD",hard_msgs},
4551 {0x04,"ERRXOS",NULL},
4552 {0xE1,"ERRRMX1",NULL},
4553 {0xE2,"ERRRMX2",NULL},
4554 {0xE3,"ERRRMX3",NULL},
4555 {0xFF,"ERRCMD",NULL},
4559 /****************************************************************************
4560 return a SMB error string from a SMB buffer
4561 ****************************************************************************/
4562 char *smb_errstr(char *inbuf)
4565 int class = CVAL(inbuf,smb_rcls);
4566 int num = SVAL(inbuf,smb_err);
4569 for (i=0;err_classes[i].class;i++)
4570 if (err_classes[i].code == class)
4572 if (err_classes[i].err_msgs)
4574 err_code_struct *err = err_classes[i].err_msgs;
4575 for (j=0;err[j].name;j++)
4576 if (num == err[j].code)
4579 sprintf(ret,"%s - %s (%s)",err_classes[i].class,
4580 err[j].name,err[j].message);
4582 sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
4587 sprintf(ret,"%s - %d",err_classes[i].class,num);
4591 sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);