2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1994-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 pstring cur_dir = "\\";
38 pstring password = "";
40 pstring workgroup=WORKGROUP;
41 BOOL got_pass = False;
42 BOOL connect_as_printer = False;
43 BOOL connect_as_ipc = False;
44 extern struct in_addr bcast_ip;
45 static BOOL got_bcast=False;
50 extern pstring user_socket_options;
52 /* 30 second timeout on most commands */
53 #define CLIENT_TIMEOUT (30*1000)
54 #define SHORT_TIMEOUT (5*1000)
56 /* value for unused fid field in trans2 secondary request */
57 #define FID_UNUSED (0xFFFF)
61 int max_protocol = PROTOCOL_NT1;
64 time_t newer_than = 0;
65 int archive_level = 0;
67 extern struct in_addr myip;
69 extern pstring debugf;
70 extern int DEBUGLEVEL;
72 BOOL translation = False;
74 /* clitar bits insert */
75 extern void cmd_tar();
76 extern void cmd_block();
77 extern void cmd_tarmode();
78 extern void cmd_setmode();
81 extern BOOL tar_reset;
82 extern int process_tar();
83 extern int tar_parseargs();
94 int max_xmit = BUFFER_SIZE;
102 BOOL recurse = False;
103 BOOL lowercase = False;
105 BOOL have_ip = False;
107 struct in_addr dest_ip;
109 #define SEPARATORS " \t\n\r"
111 BOOL abort_mget = True;
115 BOOL readbraw_supported = False;
116 BOOL writebraw_supported = False;
118 pstring fileselection = "";
120 extern file_info def_finfo;
123 int get_total_size = 0;
124 int get_total_time_ms = 0;
125 int put_total_size = 0;
126 int put_total_time_ms = 0;
134 extern int coding_system;
135 #define CNV_LANG(s) (coding_system == DOSV_CODE?s:dos_to_unix(s, False))
136 #define CNV_INPUT(s) (coding_system == DOSV_CODE?s:unix_to_dos(s, True))
138 setup_term_code (char *code)
141 new = interpret_coding_system (code, UNKNOWN_CODE);
142 if (new != UNKNOWN_CODE) {
149 #define CNV_LANG(s) dos2unix_format(s,False)
150 #define CNV_INPUT(s) unix2dos_format(s,True)
153 static void send_logout(void );
154 BOOL reopen_connection(char *inbuf,char *outbuf);
155 static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
156 static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
157 static BOOL call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,
158 int *rprcnt,int *rdrcnt,char *param,char *data,
159 char **rparam,char **rdata);
160 static BOOL send_trans_request(char *outbuf,int trans,
161 char *name,int fid,int flags,
162 char *data,char *param,uint16 *setup,
163 int ldata,int lparam,int lsetup,
164 int mdata,int mparam,int msetup);
167 /****************************************************************************
168 setup basics in a outgoing packet
169 ****************************************************************************/
170 void setup_pkt(char *outbuf)
172 SSVAL(outbuf,smb_pid,pid);
173 SSVAL(outbuf,smb_uid,uid);
174 SSVAL(outbuf,smb_mid,mid);
175 if (Protocol > PROTOCOL_CORE)
177 SCVAL(outbuf,smb_flg,0x8);
178 SSVAL(outbuf,smb_flg2,0x1);
182 /****************************************************************************
183 write to a local file with CR/LF->LF translation if appropriate. return the
184 number taken from the buffer. This may not equal the number written.
185 ****************************************************************************/
186 static int writefile(int f, char *b, int n)
191 return(write(f,b,n));
196 if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n')
200 if (write(f, b, 1) != 1)
211 /****************************************************************************
212 read from a file with LF->CR/LF translation if appropriate. return the
213 number read. read approx n bytes.
214 ****************************************************************************/
215 static int readfile(char *b, int size, int n, FILE *f)
220 if (!translation || (size != 1))
221 return(fread(b,size,n,f));
226 if ((c = getc(f)) == EOF)
231 if (c == '\n') /* change all LFs to CR/LF */
244 /****************************************************************************
245 read from a file with print translation. return the number read. read approx n
247 ****************************************************************************/
248 static int printread(FILE *f,char *b,int n)
252 i = readfile(b,1, n-1,f);
261 /****************************************************************************
262 check for existance of a dir
263 ****************************************************************************/
264 static BOOL chkpath(char *path,BOOL report)
267 pstring inbuf,outbuf;
271 trim_string(path2,NULL,"\\");
272 if (!*path2) *path2 = '\\';
274 bzero(outbuf,smb_size);
275 set_message(outbuf,0,4 + strlen(path2),True);
276 SCVAL(outbuf,smb_com,SMBchkpth);
277 SSVAL(outbuf,smb_tid,cnum);
284 send_smb(Client,outbuf);
285 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
287 if (report && CVAL(inbuf,smb_rcls) != 0)
288 DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
290 return(CVAL(inbuf,smb_rcls) == 0);
294 /****************************************************************************
296 ****************************************************************************/
297 static void send_message(char *inbuf,char *outbuf)
304 /* send a SMBsendstrt command */
305 bzero(outbuf,smb_size);
306 set_message(outbuf,0,0,True);
307 CVAL(outbuf,smb_com) = SMBsendstrt;
308 SSVAL(outbuf,smb_tid,cnum);
313 p = skip_string(p,1);
316 p = skip_string(p,1);
318 set_message(outbuf,0,PTR_DIFF(p,smb_buf(outbuf)),False);
320 send_smb(Client,outbuf);
323 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
325 printf("SMBsendstrt failed. (%s)\n",smb_errstr(inbuf));
329 grp_id = SVAL(inbuf,smb_vwv0);
331 printf("Connected. Type your message, ending it with a Control-D\n");
333 while (!feof(stdin) && total_len < 1600)
335 int maxlen = MIN(1600 - total_len,127);
342 for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++)
349 CVAL(outbuf,smb_com) = SMBsendtxt;
351 set_message(outbuf,1,l+3,True);
353 SSVAL(outbuf,smb_vwv0,grp_id);
360 send_smb(Client,outbuf);
363 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
365 printf("SMBsendtxt failed (%s)\n",smb_errstr(inbuf));
372 if (total_len >= 1600)
373 printf("the message was truncated to 1600 bytes ");
375 printf("sent %d bytes ",total_len);
377 printf("(status was %d-%d)\n",CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err));
379 CVAL(outbuf,smb_com) = SMBsendend;
380 set_message(outbuf,1,0,False);
381 SSVAL(outbuf,smb_vwv0,grp_id);
383 send_smb(Client,outbuf);
386 if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
388 printf("SMBsendend failed (%s)\n",smb_errstr(inbuf));
395 /****************************************************************************
396 check the space on a device
397 ****************************************************************************/
398 static void do_dskattr(void)
400 pstring inbuf,outbuf;
402 bzero(outbuf,smb_size);
403 set_message(outbuf,0,0,True);
404 CVAL(outbuf,smb_com) = SMBdskattr;
405 SSVAL(outbuf,smb_tid,cnum);
408 send_smb(Client,outbuf);
409 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
411 if (CVAL(inbuf,smb_rcls) != 0)
412 DEBUG(0,("Error in dskattr: %s\n",smb_errstr(inbuf)));
414 DEBUG(0,("\n\t\t%d blocks of size %d. %d blocks available\n",
415 SVAL(inbuf,smb_vwv0),
416 SVAL(inbuf,smb_vwv1)*SVAL(inbuf,smb_vwv2),
417 SVAL(inbuf,smb_vwv3)));
420 /****************************************************************************
422 ****************************************************************************/
423 static void cmd_pwd(void)
425 DEBUG(0,("Current directory is %s",CNV_LANG(service)));
426 DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
430 /****************************************************************************
431 change directory - inner section
432 ****************************************************************************/
433 static void do_cd(char *newdir)
439 /* Save the current directory in case the
440 new directory is invalid */
441 strcpy(saved_dir, cur_dir);
446 if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
447 strcat(cur_dir, "\\");
449 dos_clean_name(cur_dir);
450 strcpy(dname,cur_dir);
451 strcat(cur_dir,"\\");
452 dos_clean_name(cur_dir);
454 if (!strequal(cur_dir,"\\"))
455 if (!chkpath(dname,True))
456 strcpy(cur_dir,saved_dir);
458 strcpy(cd_path,cur_dir);
461 /****************************************************************************
463 ****************************************************************************/
464 static void cmd_cd(char *inbuf,char *outbuf)
468 if (next_token(NULL,buf,NULL))
471 DEBUG(0,("Current directory is %s\n",CNV_LANG(cur_dir)));
475 /****************************************************************************
476 display info about a file
477 ****************************************************************************/
478 static void display_finfo(file_info *finfo)
480 time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
481 DEBUG(0,(" %-30s%7.7s%10d %s",
482 CNV_LANG(finfo->name),
483 attrib_string(finfo->mode),
485 asctime(LocalTime(&t,GMT_TO_LOCAL))));
488 /****************************************************************************
489 do a directory listing, calling fn on each file found
490 ****************************************************************************/
491 void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
493 DEBUG(5,("do_dir(%s,%x,%s)\n",Mask,attribute,BOOLSTR(recurse_dir)));
494 if (Protocol >= PROTOCOL_LANMAN2)
496 if (do_long_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir) > 0)
500 expand_mask(Mask,False);
501 do_short_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir);
505 /*******************************************************************
506 decide if a file should be operated on
507 ********************************************************************/
508 static BOOL do_this_one(file_info *finfo)
510 if (finfo->mode & aDIR) return(True);
512 if (newer_than && finfo->mtime < newer_than)
515 if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH))
521 /****************************************************************************
522 interpret a short filename structure
523 The length of the structure is returned
524 ****************************************************************************/
525 static int interpret_short_filename(char *p,file_info *finfo)
527 finfo->mode = CVAL(p,21);
529 /* this date is converted to GMT by make_unix_date */
530 finfo->ctime = make_unix_date(p+22);
531 finfo->mtime = finfo->atime = finfo->ctime;
532 finfo->size = IVAL(p,26);
533 strcpy(finfo->name,p+30);
535 return(DIR_STRUCT_SIZE);
538 /****************************************************************************
539 interpret a long filename structure - this is mostly guesses at the moment
540 The length of the structure is returned
541 The structure of a long filename depends on the info level. 260 is used
542 by NT and 2 is used by OS/2
543 ****************************************************************************/
544 static int interpret_long_filename(int level,char *p,file_info *finfo)
547 memcpy(finfo,&def_finfo,sizeof(*finfo));
551 case 1: /* OS/2 understands this */
554 /* these dates are converted to GMT by make_unix_date */
555 finfo->ctime = make_unix_date2(p+4);
556 finfo->atime = make_unix_date2(p+8);
557 finfo->mtime = make_unix_date2(p+12);
558 finfo->size = IVAL(p,16);
559 finfo->mode = CVAL(p,24);
560 strcpy(finfo->name,p+27);
562 return(28 + CVAL(p,26));
564 case 2: /* this is what OS/2 uses mostly */
567 /* these dates are converted to GMT by make_unix_date */
568 finfo->ctime = make_unix_date2(p+4);
569 finfo->atime = make_unix_date2(p+8);
570 finfo->mtime = make_unix_date2(p+12);
571 finfo->size = IVAL(p,16);
572 finfo->mode = CVAL(p,24);
573 strcpy(finfo->name,p+31);
575 return(32 + CVAL(p,30));
577 /* levels 3 and 4 are untested */
581 /* these dates are probably like the other ones */
582 finfo->ctime = make_unix_date2(p+8);
583 finfo->atime = make_unix_date2(p+12);
584 finfo->mtime = make_unix_date2(p+16);
585 finfo->size = IVAL(p,20);
586 finfo->mode = CVAL(p,28);
587 strcpy(finfo->name,p+33);
594 /* these dates are probably like the other ones */
595 finfo->ctime = make_unix_date2(p+8);
596 finfo->atime = make_unix_date2(p+12);
597 finfo->mtime = make_unix_date2(p+16);
598 finfo->size = IVAL(p,20);
599 finfo->mode = CVAL(p,28);
600 strcpy(finfo->name,p+37);
604 case 260: /* NT uses this, but also accepts 2 */
609 p += 4; /* next entry offset */
610 p += 4; /* fileindex */
612 /* these dates appear to arrive in a weird way. It seems to
613 be localtime plus the serverzone given in the initial
614 connect. This is GMT when DST is not in effect and one
615 hour from GMT otherwise. Can this really be right??
617 I suppose this could be called kludge-GMT. Is is the GMT
618 you get by using the current DST setting on a different
619 localtime. It will be cheap to calculate, I suppose, as
620 no DST tables will be needed */
622 finfo->ctime = interpret_long_date(p); p += 8;
623 finfo->atime = interpret_long_date(p); p += 8;
624 finfo->mtime = interpret_long_date(p); p += 8; p += 8;
625 finfo->size = IVAL(p,0); p += 8;
626 p += 8; /* alloc size */
627 finfo->mode = CVAL(p,0); p += 4;
628 namelen = IVAL(p,0); p += 4;
629 p += 4; /* EA size */
630 p += 2; /* short name len? */
631 p += 24; /* short name? */
632 StrnCpy(finfo->name,p,namelen);
638 DEBUG(1,("Unknown long filename format %d\n",level));
645 /****************************************************************************
646 act on the files in a dir listing
647 ****************************************************************************/
648 static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir)
651 if (!((finfo->mode & aDIR) == 0 && *fileselection &&
652 !mask_match(finfo->name,fileselection,False,False)) &&
653 !(recurse_dir && (strequal(finfo->name,".") ||
654 strequal(finfo->name,".."))))
656 if (recurse_dir && (finfo->mode & aDIR))
660 strcpy(sav_dir,cur_dir);
661 strcat(cur_dir,finfo->name);
662 strcat(cur_dir,"\\");
663 strcpy(mask2,cur_dir);
666 DEBUG(0,("\n%s\n",CNV_LANG(cur_dir)));
671 do_long_dir(inbuf,outbuf,mask2,attribute,fn,True);
673 do_dir(inbuf,outbuf,mask2,attribute,fn,True);
675 strcpy(cur_dir,sav_dir);
679 if (fn && do_this_one(finfo))
686 /****************************************************************************
687 do a directory listing, calling fn on each file found
688 ****************************************************************************/
689 static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
695 int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
696 int num_received = 0;
698 char *dirlist = NULL;
710 bzero(outbuf,smb_size);
712 set_message(outbuf,2,5 + strlen(mask),True);
714 set_message(outbuf,2,5 + 21,True);
717 if (Protocol >= PROTOCOL_LANMAN1)
718 CVAL(outbuf,smb_com) = SMBffirst;
721 CVAL(outbuf,smb_com) = SMBsearch;
723 SSVAL(outbuf,smb_tid,cnum);
726 SSVAL(outbuf,smb_vwv0,num_asked);
727 SSVAL(outbuf,smb_vwv1,attribute);
748 send_smb(Client,outbuf);
749 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
751 received = SVAL(inbuf,smb_vwv0);
753 DEBUG(5,("dir received %d\n",received));
755 DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
757 if (received <= 0) break;
761 dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
766 p = smb_buf(inbuf) + 3;
768 memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
769 p,received*DIR_STRUCT_SIZE);
771 memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
773 num_received += received;
775 if (CVAL(inbuf,smb_rcls) != 0) break;
779 if (!first && Protocol >= PROTOCOL_LANMAN1)
781 bzero(outbuf,smb_size);
782 CVAL(outbuf,smb_com) = SMBfclose;
784 SSVAL(outbuf,smb_tid,cnum);
798 send_smb(Client,outbuf);
799 receive_smb(Client,inbuf,CLIENT_TIMEOUT,False);
801 if (CVAL(inbuf,smb_rcls) != 0)
802 DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));
807 for (p=dirlist,i=0;i<num_received;i++)
809 p += interpret_short_filename(p,&finfo);
810 display_finfo(&finfo);
813 for (p=dirlist,i=0;i<num_received;i++)
815 p += interpret_short_filename(p,&finfo);
816 dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
819 if (dirlist) free(dirlist);
820 return(num_received);
823 /****************************************************************************
824 receive a SMB trans or trans2 response allocating the necessary memory
825 ****************************************************************************/
826 static BOOL receive_trans_response(char *inbuf,int trans,
827 int *data_len,int *param_len,
828 char **data,char **param)
832 int this_data,this_param;
834 *data_len = *param_len = 0;
836 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
840 if (CVAL(inbuf,smb_com) != trans)
842 DEBUG(0,("Expected %s response, got command 0x%02x\n",
843 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
846 if (CVAL(inbuf,smb_rcls) != 0)
849 /* parse out the lengths */
850 total_data = SVAL(inbuf,smb_tdrcnt);
851 total_param = SVAL(inbuf,smb_tprcnt);
854 *data = Realloc(*data,total_data);
855 *param = Realloc(*param,total_param);
859 this_data = SVAL(inbuf,smb_drcnt);
860 this_param = SVAL(inbuf,smb_prcnt);
862 memcpy(*data + SVAL(inbuf,smb_drdisp),
863 smb_base(inbuf) + SVAL(inbuf,smb_droff),
866 memcpy(*param + SVAL(inbuf,smb_prdisp),
867 smb_base(inbuf) + SVAL(inbuf,smb_proff),
869 *data_len += this_data;
870 *param_len += this_param;
872 /* parse out the total lengths again - they can shrink! */
873 total_data = SVAL(inbuf,smb_tdrcnt);
874 total_param = SVAL(inbuf,smb_tprcnt);
876 if (total_data <= *data_len && total_param <= *param_len)
879 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
883 if (CVAL(inbuf,smb_com) != trans)
885 DEBUG(0,("Expected %s response, got command 0x%02x\n",
886 trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
889 if (CVAL(inbuf,smb_rcls) != 0)
896 /****************************************************************************
897 do a directory listing, calling fn on each file found. Use the TRANSACT2
898 call for long filenames
899 ****************************************************************************/
900 static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
902 int max_matches = 512;
903 int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
908 char *dirlist = NULL;
910 int total_received = 0;
912 char *resp_data=NULL;
913 char *resp_param=NULL;
914 int resp_data_len = 0;
915 int resp_param_len=0;
917 int ff_resume_key = 0;
918 int ff_searchcount=0;
932 if (loop_count > 200)
934 DEBUG(0,("ERROR: Looping in FIND_NEXT??\n"));
940 setup = TRANSACT2_FINDFIRST;
941 SSVAL(param,0,attribute); /* attribute */
942 SSVAL(param,2,max_matches); /* max count */
943 SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
944 SSVAL(param,6,info_level);
946 strcpy(param+12,mask);
950 setup = TRANSACT2_FINDNEXT;
951 SSVAL(param,0,ff_dir_handle);
952 SSVAL(param,2,max_matches); /* max count */
953 SSVAL(param,4,info_level);
954 SIVAL(param,6,ff_resume_key); /* ff_resume_key */
955 SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
956 strcpy(param+12,mask);
958 DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
959 ff_dir_handle,ff_resume_key,ff_lastname,mask));
961 /* ??? original code added 1 pad byte after param */
963 send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
965 0,12+strlen(mask)+1,1,
968 if (!receive_trans_response(inbuf,SMBtrans2,
969 &resp_data_len,&resp_param_len,
970 &resp_data,&resp_param))
972 DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
976 /* parse out some important return info */
980 ff_dir_handle = SVAL(p,0);
981 ff_searchcount = SVAL(p,2);
983 ff_lastname = SVAL(p,8);
987 ff_searchcount = SVAL(p,0);
989 ff_lastname = SVAL(p,6);
992 if (ff_searchcount == 0)
995 /* point to the data bytes */
998 /* we might need the lastname for continuations */
1005 StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
1006 /* strcpy(mask,p+ff_lastname+94); */
1009 strcpy(mask,p + ff_lastname + 1);
1017 /* and add them to the dirlist pool */
1018 dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
1022 DEBUG(0,("Failed to expand dirlist\n"));
1026 /* put in a length for the last entry, to ensure we can chain entries
1027 into the next packet */
1030 for (p2=p,i=0;i<(ff_searchcount-1);i++)
1031 p2 += interpret_long_filename(info_level,p2,NULL);
1032 SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
1035 /* grab the data for later use */
1036 memcpy(dirlist+dirlist_len,p,resp_data_len);
1037 dirlist_len += resp_data_len;
1039 total_received += ff_searchcount;
1041 if (resp_data) free(resp_data); resp_data = NULL;
1042 if (resp_param) free(resp_param); resp_param = NULL;
1044 DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
1045 ff_searchcount,ff_eos,ff_resume_key));
1051 for (p=dirlist,i=0;i<total_received;i++)
1053 p += interpret_long_filename(info_level,p,&finfo);
1054 display_finfo(&finfo);
1057 for (p=dirlist,i=0;i<total_received;i++)
1059 p += interpret_long_filename(info_level,p,&finfo);
1060 dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
1063 /* free up the dirlist buffer */
1064 if (dirlist) free(dirlist);
1065 return(total_received);
1069 /****************************************************************************
1070 get a directory listing
1071 ****************************************************************************/
1072 static void cmd_dir(char *inbuf,char *outbuf)
1074 int attribute = aDIR | aSYSTEM | aHIDDEN;
1079 strcpy(mask,cur_dir);
1080 if(mask[strlen(mask)-1]!='\\')
1083 if (next_token(NULL,buf,NULL))
1094 do_dir(inbuf,outbuf,mask,attribute,NULL,recurse);
1101 /****************************************************************************
1102 get a file from rname to lname
1103 ****************************************************************************/
1104 static void do_get(char *rname,char *lname,file_info *finfo1)
1109 BOOL newhandle = False;
1110 char *inbuf,*outbuf;
1112 BOOL close_done = False;
1113 BOOL ignore_close_error = False;
1117 struct timeval tp_start;
1118 GetTimeOfDay(&tp_start);
1129 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1130 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1132 if (!inbuf || !outbuf)
1134 DEBUG(0,("out of memory\n"));
1138 bzero(outbuf,smb_size);
1139 set_message(outbuf,15,1 + strlen(rname),True);
1141 CVAL(outbuf,smb_com) = SMBopenX;
1142 SSVAL(outbuf,smb_tid,cnum);
1145 SSVAL(outbuf,smb_vwv0,0xFF);
1146 SSVAL(outbuf,smb_vwv2,1);
1147 SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
1148 SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
1149 SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
1150 SSVAL(outbuf,smb_vwv8,1);
1152 p = smb_buf(outbuf);
1154 p = skip_string(p,1);
1156 /* do a chained openX with a readX? */
1160 DEBUG(3,("Chaining readX wth openX\n"));
1161 SSVAL(outbuf,smb_vwv0,SMBreadX);
1162 SSVAL(outbuf,smb_vwv1,smb_offset(p,outbuf));
1165 SSVAL(p,smb_wct,10);
1166 SSVAL(p,smb_vwv0,0xFF);
1167 SSVAL(p,smb_vwv5,MIN(max_xmit-500,finfo.size));
1168 SSVAL(p,smb_vwv9,MIN(BUFFER_SIZE,finfo.size));
1169 smb_setlen(outbuf,smb_len(outbuf)+11*2+1);
1173 if(!strcmp(lname,"-"))
1174 handle = fileno(stdout);
1177 handle = creat(lname,0644);
1182 DEBUG(0,("Error opening local file %s\n",lname));
1183 free(inbuf);free(outbuf);
1187 send_smb(Client,outbuf);
1188 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1190 if (CVAL(inbuf,smb_rcls) != 0)
1192 if (CVAL(inbuf,smb_rcls) == ERRSRV &&
1193 SVAL(inbuf,smb_err) == ERRnoresource &&
1194 reopen_connection(inbuf,outbuf))
1196 do_get(rname,lname,finfo1);
1199 DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
1202 free(inbuf);free(outbuf);
1206 strcpy(finfo.name,rname);
1210 finfo.mode = SVAL(inbuf,smb_vwv3);
1211 /* these times arrive as LOCAL time, using the DST offset
1212 corresponding to that time, we convert them to GMT */
1213 finfo.mtime = make_unix_date3(inbuf+smb_vwv4);
1214 finfo.atime = finfo.ctime = finfo.mtime;
1215 finfo.size = IVAL(inbuf,smb_vwv6);
1218 DEBUG(3,("file %s attrib 0x%X\n",CNV_LANG(finfo.name),finfo.mode));
1220 fnum = SVAL(inbuf,smb_vwv2);
1222 /* we might have got some data from a chained readX */
1223 if (SVAL(inbuf,smb_vwv0) == SMBreadX)
1225 p = (smb_base(inbuf)+SVAL(inbuf,smb_vwv1)) - smb_wct;
1226 datalen = SVAL(p,smb_vwv5);
1227 dataptr = smb_base(inbuf) + SVAL(p,smb_vwv6);
1236 DEBUG(2,("getting file %s of size %d bytes as %s ",
1237 CNV_LANG(finfo.name),
1241 while (nread < finfo.size && !close_done)
1244 static BOOL can_chain_close = True;
1248 DEBUG(3,("nread=%d max_xmit=%d fsize=%d\n",nread,max_xmit,finfo.size));
1250 /* 3 possible read types. readbraw if a large block is required.
1251 readX + close if not much left and read if neither is supported */
1253 /* we might have already read some data from a chained readX */
1254 if (dataptr && datalen>0)
1257 /* if we can finish now then readX+close */
1258 if (method<0 && can_chain_close && (Protocol >= PROTOCOL_LANMAN1) &&
1259 ((finfo.size - nread) <
1260 (max_xmit - (2*smb_size + 13*SIZEOFWORD + 300))))
1263 /* if we support readraw then use that */
1264 if (method<0 && readbraw_supported)
1267 /* if we can then use readX */
1268 if (method<0 && (Protocol >= PROTOCOL_LANMAN1))
1279 /* use readX + close */
1280 bzero(outbuf,smb_size);
1281 set_message(outbuf,10,0,True);
1282 CVAL(outbuf,smb_com) = SMBreadX;
1283 SSVAL(outbuf,smb_tid,cnum);
1288 CVAL(outbuf,smb_vwv0) = SMBclose;
1289 SSVAL(outbuf,smb_vwv1,smb_offset(smb_buf(outbuf),outbuf));
1292 CVAL(outbuf,smb_vwv0) = 0xFF;
1294 SSVAL(outbuf,smb_vwv2,fnum);
1295 SIVAL(outbuf,smb_vwv3,nread);
1296 SSVAL(outbuf,smb_vwv5,MIN(max_xmit-200,finfo.size - nread));
1297 SSVAL(outbuf,smb_vwv6,0);
1298 SIVAL(outbuf,smb_vwv7,0);
1299 SSVAL(outbuf,smb_vwv9,MIN(BUFFER_SIZE,finfo.size-nread));
1303 p = smb_buf(outbuf);
1310 /* now set the total packet length */
1311 smb_setlen(outbuf,smb_len(outbuf)+9);
1314 send_smb(Client,outbuf);
1315 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1317 if (CVAL(inbuf,smb_rcls) != 0)
1319 DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
1324 SVAL(inbuf,smb_vwv0) != SMBclose)
1326 /* NOTE: WfWg sometimes just ignores the chained
1327 command! This seems to break the spec? */
1328 DEBUG(3,("Rejected chained close?\n"));
1330 can_chain_close = False;
1331 ignore_close_error = True;
1334 datalen = SVAL(inbuf,smb_vwv5);
1335 dataptr = smb_base(inbuf) + SVAL(inbuf,smb_vwv6);
1341 static int readbraw_size = BUFFER_SIZE;
1344 bzero(outbuf,smb_size);
1345 set_message(outbuf,8,0,True);
1346 CVAL(outbuf,smb_com) = SMBreadbraw;
1347 SSVAL(outbuf,smb_tid,cnum);
1349 SSVAL(outbuf,smb_vwv0,fnum);
1350 SIVAL(outbuf,smb_vwv1,nread);
1351 SSVAL(outbuf,smb_vwv3,MIN(finfo.size-nread,readbraw_size));
1352 SSVAL(outbuf,smb_vwv4,0);
1353 SIVALS(outbuf,smb_vwv5,-1);
1354 send_smb(Client,outbuf);
1356 /* Now read the raw data into the buffer and write it */
1357 if(read_smb_length(Client,inbuf,0) == -1) {
1358 DEBUG(0,("Failed to read length in readbraw\n"));
1362 /* Even though this is not an smb message, smb_len
1363 returns the generic length of an smb message */
1364 datalen = smb_len(inbuf);
1368 /* we got a readbraw error */
1369 DEBUG(4,("readbraw error - reducing size\n"));
1370 readbraw_size = (readbraw_size * 9) / 10;
1372 if (readbraw_size < max_xmit)
1374 DEBUG(0,("disabling readbraw\n"));
1375 readbraw_supported = False;
1382 if(read_data(Client,inbuf,datalen) != datalen) {
1383 DEBUG(0,("Failed to read data in readbraw\n"));
1391 /* we've already read some data with a chained readX */
1395 /* use plain read */
1396 bzero(outbuf,smb_size);
1397 set_message(outbuf,5,0,True);
1398 CVAL(outbuf,smb_com) = SMBread;
1399 SSVAL(outbuf,smb_tid,cnum);
1402 SSVAL(outbuf,smb_vwv0,fnum);
1403 SSVAL(outbuf,smb_vwv1,MIN(max_xmit-200,finfo.size - nread));
1404 SIVAL(outbuf,smb_vwv2,nread);
1405 SSVAL(outbuf,smb_vwv4,finfo.size - nread);
1407 send_smb(Client,outbuf);
1408 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1410 if (CVAL(inbuf,smb_rcls) != 0)
1412 DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
1416 datalen = SVAL(inbuf,smb_vwv0);
1417 dataptr = smb_buf(inbuf) + 3;
1421 if (writefile(handle,dataptr,datalen) != datalen)
1423 DEBUG(0,("Error writing local file\n"));
1430 DEBUG(0,("Error reading file %s. Got %d bytes\n",CNV_LANG(rname),nread));
1442 bzero(outbuf,smb_size);
1443 set_message(outbuf,3,0,True);
1444 CVAL(outbuf,smb_com) = SMBclose;
1445 SSVAL(outbuf,smb_tid,cnum);
1448 SSVAL(outbuf,smb_vwv0,fnum);
1449 SIVALS(outbuf,smb_vwv1,-1);
1451 send_smb(Client,outbuf);
1452 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1454 if (!ignore_close_error && CVAL(inbuf,smb_rcls) != 0)
1456 DEBUG(0,("Error %s closing remote file\n",smb_errstr(inbuf)));
1459 free(inbuf);free(outbuf);
1467 if (archive_level >= 2 && (finfo.mode & aARCH)) {
1468 bzero(outbuf,smb_size);
1469 set_message(outbuf,8,strlen(rname)+4,True);
1470 CVAL(outbuf,smb_com) = SMBsetatr;
1471 SSVAL(outbuf,smb_tid,cnum);
1473 SSVAL(outbuf,smb_vwv0,finfo.mode & ~(aARCH));
1474 SIVALS(outbuf,smb_vwv1,0);
1475 p = smb_buf(outbuf);
1481 send_smb(Client,outbuf);
1482 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1486 struct timeval tp_end;
1489 GetTimeOfDay(&tp_end);
1491 (tp_end.tv_sec - tp_start.tv_sec)*1000 +
1492 (tp_end.tv_usec - tp_start.tv_usec)/1000;
1493 get_total_time_ms += this_time;
1494 get_total_size += finfo.size;
1496 DEBUG(2,("(%g kb/s) (average %g kb/s)\n",
1497 finfo.size / (1.024*this_time + 1.0e-4),
1498 get_total_size / (1.024*get_total_time_ms)));
1501 free(inbuf);free(outbuf);
1505 /****************************************************************************
1507 ****************************************************************************/
1508 static void cmd_get(void)
1514 strcpy(rname,cur_dir);
1517 p = rname + strlen(rname);
1519 if (!next_token(NULL,p,NULL)) {
1520 DEBUG(0,("get <filename>\n"));
1524 dos_clean_name(rname);
1526 next_token(NULL,lname,NULL);
1528 do_get(rname,lname,NULL);
1532 /****************************************************************************
1533 do a mget operation on one file
1534 ****************************************************************************/
1535 static void do_mget(file_info *finfo)
1540 if (strequal(finfo->name,".") || strequal(finfo->name,".."))
1545 DEBUG(0,("mget aborted\n"));
1549 if (finfo->mode & aDIR)
1550 sprintf(quest,"Get directory %s? ",CNV_LANG(finfo->name));
1552 sprintf(quest,"Get file %s? ",CNV_LANG(finfo->name));
1554 if (prompt && !yesno(quest)) return;
1556 if (finfo->mode & aDIR)
1558 pstring saved_curdir;
1560 char *inbuf,*outbuf;
1562 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1563 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1565 if (!inbuf || !outbuf)
1567 DEBUG(0,("out of memory\n"));
1571 strcpy(saved_curdir,cur_dir);
1573 strcat(cur_dir,finfo->name);
1574 strcat(cur_dir,"\\");
1576 unix_format(finfo->name);
1579 strlower(finfo->name);
1581 if (!directory_exist(finfo->name,NULL) &&
1582 sys_mkdir(finfo->name,0777) != 0)
1584 DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
1585 strcpy(cur_dir,saved_curdir);
1586 free(inbuf);free(outbuf);
1590 if (sys_chdir(finfo->name) != 0)
1592 DEBUG(0,("failed to chdir to directory %s\n",CNV_LANG(finfo->name)));
1593 strcpy(cur_dir,saved_curdir);
1594 free(inbuf);free(outbuf);
1599 strcpy(mget_mask,cur_dir);
1600 strcat(mget_mask,"*");
1602 do_dir((char *)inbuf,(char *)outbuf,
1603 mget_mask,aSYSTEM | aHIDDEN | aDIR,do_mget,False);
1605 strcpy(cur_dir,saved_curdir);
1606 free(inbuf);free(outbuf);
1610 strcpy(rname,cur_dir);
1611 strcat(rname,finfo->name);
1612 do_get(rname,finfo->name,finfo);
1616 /****************************************************************************
1617 view the file using the pager
1618 ****************************************************************************/
1619 static void cmd_more(void)
1621 fstring rname,lname,tmpname,pager_cmd;
1624 strcpy(rname,cur_dir);
1626 sprintf(tmpname,"/tmp/smbmore.%d",getpid());
1627 strcpy(lname,tmpname);
1629 if (!next_token(NULL,rname+strlen(rname),NULL)) {
1630 DEBUG(0,("more <filename>\n"));
1633 dos_clean_name(rname);
1635 do_get(rname,lname,NULL);
1637 pager=getenv("PAGER");
1638 sprintf(pager_cmd,"%s %s",(pager? pager:PAGER), tmpname);
1645 /****************************************************************************
1647 ****************************************************************************/
1648 static void cmd_mget(char *inbuf,char *outbuf)
1650 int attribute = aSYSTEM | aHIDDEN;
1662 while (next_token(NULL,p,NULL))
1664 strcpy(mget_mask,cur_dir);
1665 if(mget_mask[strlen(mget_mask)-1]!='\\')
1666 strcat(mget_mask,"\\");
1669 strcpy(mget_mask,p);
1671 strcat(mget_mask,p);
1672 do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
1677 strcpy(mget_mask,cur_dir);
1678 if(mget_mask[strlen(mget_mask)-1]!='\\')
1679 strcat(mget_mask,"\\");
1680 strcat(mget_mask,"*");
1681 do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
1685 /****************************************************************************
1686 make a directory of name "name"
1687 ****************************************************************************/
1688 static BOOL do_mkdir(char *name)
1691 char *inbuf,*outbuf;
1693 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1694 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1696 if (!inbuf || !outbuf)
1698 DEBUG(0,("out of memory\n"));
1702 bzero(outbuf,smb_size);
1703 set_message(outbuf,0,2 + strlen(name),True);
1705 CVAL(outbuf,smb_com) = SMBmkdir;
1706 SSVAL(outbuf,smb_tid,cnum);
1710 p = smb_buf(outbuf);
1714 send_smb(Client,outbuf);
1715 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1717 if (CVAL(inbuf,smb_rcls) != 0)
1719 DEBUG(0,("%s making remote directory %s\n",
1720 smb_errstr(inbuf),CNV_LANG(name)));
1722 free(inbuf);free(outbuf);
1726 free(inbuf);free(outbuf);
1731 /****************************************************************************
1733 ****************************************************************************/
1734 static void cmd_mkdir(char *inbuf,char *outbuf)
1740 strcpy(mask,cur_dir);
1742 if (!next_token(NULL,p,NULL))
1745 DEBUG(0,("mkdir <dirname>\n"));
1757 trim_string(ddir,".",NULL);
1758 p = strtok(ddir,"/\\");
1762 if (!chkpath(ddir2,False))
1767 p = strtok(NULL,"/\\");
1775 /*******************************************************************
1776 write to a file using writebraw
1777 ********************************************************************/
1778 static int smb_writeraw(char *outbuf,int fnum,int pos,char *buf,int n)
1783 bzero(outbuf,smb_size);
1784 bzero(inbuf,smb_size);
1785 set_message(outbuf,Protocol>PROTOCOL_COREPLUS?12:10,0,True);
1787 CVAL(outbuf,smb_com) = SMBwritebraw;
1788 SSVAL(outbuf,smb_tid,cnum);
1791 SSVAL(outbuf,smb_vwv0,fnum);
1792 SSVAL(outbuf,smb_vwv1,n);
1793 SIVAL(outbuf,smb_vwv3,pos);
1794 SSVAL(outbuf,smb_vwv7,1);
1796 send_smb(Client,outbuf);
1798 if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
1801 _smb_setlen(buf-4,n); /* HACK! XXXX */
1803 if (write_socket(Client,buf-4,n+4) != n+4)
1806 if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0) {
1807 DEBUG(0,("Error writing remote file (2)\n"));
1810 return(SVAL(inbuf,smb_vwv0));
1815 /*******************************************************************
1817 ********************************************************************/
1818 static int smb_writefile(char *outbuf,int fnum,int pos,char *buf,int n)
1822 if (writebraw_supported && n > (max_xmit-200))
1823 return(smb_writeraw(outbuf,fnum,pos,buf,n));
1825 bzero(outbuf,smb_size);
1826 bzero(inbuf,smb_size);
1827 set_message(outbuf,5,n + 3,True);
1829 CVAL(outbuf,smb_com) = SMBwrite;
1830 SSVAL(outbuf,smb_tid,cnum);
1833 SSVAL(outbuf,smb_vwv0,fnum);
1834 SSVAL(outbuf,smb_vwv1,n);
1835 SIVAL(outbuf,smb_vwv2,pos);
1836 SSVAL(outbuf,smb_vwv4,0);
1837 CVAL(smb_buf(outbuf),0) = 1;
1838 SSVAL(smb_buf(outbuf),1,n);
1840 memcpy(smb_buf(outbuf)+3,buf,n);
1842 send_smb(Client,outbuf);
1843 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1845 if (CVAL(inbuf,smb_rcls) != 0) {
1846 DEBUG(0,("%s writing remote file\n",smb_errstr(inbuf)));
1849 return(SVAL(inbuf,smb_vwv0));
1854 /****************************************************************************
1856 ****************************************************************************/
1857 static void do_put(char *rname,char *lname,file_info *finfo)
1863 char *inbuf,*outbuf;
1864 time_t close_time = finfo->mtime;
1866 static int maxwrite=0;
1868 struct timeval tp_start;
1869 GetTimeOfDay(&tp_start);
1871 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1872 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1874 if (!inbuf || !outbuf)
1876 DEBUG(0,("out of memory\n"));
1880 bzero(outbuf,smb_size);
1881 set_message(outbuf,3,2 + strlen(rname),True);
1883 if (finfo->mtime == 0 || finfo->mtime == -1)
1884 finfo->mtime = finfo->atime = finfo->ctime = time(NULL);
1886 CVAL(outbuf,smb_com) = SMBcreate;
1887 SSVAL(outbuf,smb_tid,cnum);
1890 SSVAL(outbuf,smb_vwv0,finfo->mode);
1891 put_dos_date3(outbuf,smb_vwv1,finfo->mtime);
1893 p = smb_buf(outbuf);
1897 send_smb(Client,outbuf);
1898 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1900 if (CVAL(inbuf,smb_rcls) != 0)
1902 DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
1904 free(inbuf);free(outbuf);if (buf) free(buf);
1908 f = fopen(lname,"r");
1912 DEBUG(0,("Error opening local file %s\n",lname));
1913 free(inbuf);free(outbuf);
1918 fnum = SVAL(inbuf,smb_vwv0);
1919 if (finfo->size < 0)
1920 finfo->size = file_size(lname);
1922 DEBUG(1,("putting file %s of size %d bytes as %s ",lname,finfo->size,CNV_LANG(rname)));
1925 maxwrite = writebraw_supported?MAX(max_xmit,BUFFER_SIZE):(max_xmit-200);
1927 while (nread < finfo->size)
1932 n = MIN(n,finfo->size - nread);
1934 buf = (char *)Realloc(buf,n+4);
1936 fseek(f,nread,SEEK_SET);
1937 if ((n = readfile(buf+4,1,n,f)) < 1)
1939 DEBUG(0,("Error reading local file\n"));
1943 ret = smb_writefile(outbuf,fnum,nread,buf+4,n);
1947 DEBUG(0,("Error writing file\n"));
1960 bzero(outbuf,smb_size);
1961 set_message(outbuf,3,0,True);
1962 CVAL(outbuf,smb_com) = SMBclose;
1963 SSVAL(outbuf,smb_tid,cnum);
1966 SSVAL(outbuf,smb_vwv0,fnum);
1967 put_dos_date3(outbuf,smb_vwv1,close_time);
1969 send_smb(Client,outbuf);
1970 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
1972 if (CVAL(inbuf,smb_rcls) != 0)
1974 DEBUG(0,("%s closing remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
1976 free(inbuf);free(outbuf);
1983 free(inbuf);free(outbuf);
1987 struct timeval tp_end;
1990 GetTimeOfDay(&tp_end);
1992 (tp_end.tv_sec - tp_start.tv_sec)*1000 +
1993 (tp_end.tv_usec - tp_start.tv_usec)/1000;
1994 put_total_time_ms += this_time;
1995 put_total_size += finfo->size;
1997 DEBUG(2,("(%g kb/s) (average %g kb/s)\n",
1998 finfo->size / (1.024*this_time + 1.0e-4),
1999 put_total_size / (1.024*put_total_time_ms)));
2005 /****************************************************************************
2007 ****************************************************************************/
2008 static void cmd_put(void)
2017 strcpy(rname,cur_dir);
2021 if (!next_token(NULL,p,NULL))
2023 DEBUG(0,("put <filename>\n"));
2028 if (next_token(NULL,p,NULL))
2031 strcat(rname,lname);
2033 dos_clean_name(rname);
2037 if (!file_exist(lname,&st)) {
2038 DEBUG(0,("%s does not exist\n",lname));
2041 finfo.mtime = st.st_mtime;
2044 do_put(rname,lname,&finfo);
2047 /****************************************************************************
2048 seek in a directory/file list until you get something that doesn't start with
2050 ****************************************************************************/
2051 static BOOL seek_list(FILE *f,char *name)
2056 if (fscanf(f,"%s",s) != 1) return(False);
2057 trim_string(s,"./",NULL);
2058 if (strncmp(s,name,strlen(name)) != 0)
2069 /****************************************************************************
2070 set the file selection mask
2071 ****************************************************************************/
2072 static void cmd_select(void)
2074 strcpy(fileselection,"");
2075 next_token(NULL,fileselection,NULL);
2079 /****************************************************************************
2081 ****************************************************************************/
2082 static void cmd_mput(void)
2093 while (next_token(NULL,p,NULL))
2100 sprintf(tmpname,"/tmp/ls.smb.%d",(int)getpid());
2102 sprintf(cmd,"find . -name \"%s\" -print > %s",p,tmpname);
2104 sprintf(cmd,"/bin/ls %s > %s",p,tmpname);
2107 f = fopen(tmpname,"r");
2114 if (fscanf(f,"%s",lname) != 1) break;
2115 trim_string(lname,"./",NULL);
2119 /* check if it's a directory */
2120 if (directory_exist(lname,&st))
2122 if (!recurse) continue;
2123 sprintf(quest,"Put directory %s? ",lname);
2124 if (prompt && !yesno(quest))
2127 if (!seek_list(f,lname))
2132 strcpy(rname,cur_dir);
2133 strcat(rname,lname);
2134 if (!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,GMT_TO_LOCAL))));
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,GMT_TO_LOCAL)),
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;
3599 /* now send a SMBtrans command with api ServerEnum? */
3601 SSVAL(p,0,0x68); /* api number */
3603 strcpy(p,"WrLehDO");
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);
3618 if (call_api(PTR_DIFF(p+4,param),0,
3624 int res = SVAL(rparam,0);
3625 int converter=SVAL(rparam,2);
3630 count=SVAL(rparam,4);
3633 printf("\n\nThis machine has a browse list:\n");
3634 printf("\n\tServer Comment\n");
3635 printf("\t--------- -------\n");
3638 for (i=0;i<count;i++) {
3640 int comment_offset = IVAL(p2,22) & 0xFFFF;
3641 printf("\t%-16.16s %s\n",
3643 comment_offset?rdata+comment_offset-converter:"");
3650 if (rparam) {free(rparam); rparam = NULL;}
3651 if (rdata) {free(rdata); rdata = NULL;}
3653 SIVAL(p,0,SV_TYPE_DOMAIN_ENUM);
3655 if (call_api(PTR_DIFF(p+4,param),0,
3661 int res = SVAL(rparam,0);
3662 int converter=SVAL(rparam,2);
3667 count=SVAL(rparam,4);
3670 printf("\n\nThis machine has a workgroup list:\n");
3671 printf("\n\tWorkgroup Master\n");
3672 printf("\t--------- -------\n");
3675 for (i=0;i<count;i++) {
3677 int comment_offset = IVAL(p2,22) & 0xFFFF;
3678 printf("\t%-16.16s %s\n",
3680 comment_offset?rdata+comment_offset-converter:"");
3687 if (rparam) free(rparam);
3688 if (rdata) free(rdata);
3698 /* This defines the commands supported by this client */
3706 {"ls",cmd_dir,"<mask> list the contents of the current directory"},
3707 {"dir",cmd_dir,"<mask> list the contents of the current directory"},
3708 {"lcd",cmd_lcd,"[directory] change/report the local current working directory"},
3709 {"cd",cmd_cd,"[directory] change/report the remote directory"},
3710 {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)"},
3711 {"get",cmd_get,"<remote name> [local name] get a file"},
3712 {"mget",cmd_mget,"<mask> get all the matching files"},
3713 {"put",cmd_put,"<local name> [remote name] put a file"},
3714 {"mput",cmd_mput,"<mask> put all matching files"},
3715 {"rename",cmd_rename,"<src> <dest> rename some files"},
3716 {"more",cmd_more,"<remote name> view a remote file with your pager"},
3717 {"mask",cmd_select,"<mask> mask all filenames against this"},
3718 {"del",cmd_del,"<mask> delete all matching files"},
3719 {"rm",cmd_del,"<mask> delete all matching files"},
3720 {"mkdir",cmd_mkdir,"<directory> make a directory"},
3721 {"md",cmd_mkdir,"<directory> make a directory"},
3722 {"rmdir",cmd_rmdir,"<directory> remove a directory"},
3723 {"rd",cmd_rmdir,"<directory> remove a directory"},
3724 {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput"},
3725 {"recurse",cmd_recurse,"toggle directory recursion for mget and mput"},
3726 {"translate",cmd_translate,"toggle text translation for printing"},
3727 {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get"},
3728 {"print",cmd_print,"<file name> print a file"},
3729 {"printmode",cmd_printmode,"<graphics or text> set the print mode"},
3730 {"queue",cmd_queue,"show the print queue"},
3731 {"cancel",cmd_cancel,"<jobid> cancel a print queue entry"},
3732 {"stat",cmd_stat,"<file> get info on a file (experimental!)"},
3733 {"quit",send_logout,"logoff the server"},
3734 {"q",send_logout,"logoff the server"},
3735 {"exit",send_logout,"logoff the server"},
3736 {"newer",cmd_newer,"<file> only mget files newer than the specified local file"},
3737 {"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"},
3738 {"tar",cmd_tar,"tar <c|x>[IXbgNa] current directory to/from <file name>" },
3739 {"blocksize",cmd_block,"blocksize <number> (default 20)" },
3740 {"tarmode",cmd_tarmode,
3741 "<full|inc|reset|noreset> tar's behaviour towards archive bits" },
3742 {"setmode",cmd_setmode,"filename <setmode string> change modes of file"},
3743 {"help",cmd_help,"[command] give help on a command"},
3744 {"?",cmd_help,"[command] give help on a command"},
3745 {"!",NULL,"run a shell command on the local system"},
3750 /*******************************************************************
3751 lookup a command string in the list of commands, including
3753 ******************************************************************/
3754 static int process_tok(fstring tok)
3756 int i = 0, matches = 0;
3758 int tok_len = strlen(tok);
3760 while (commands[i].fn != NULL)
3762 if (strequal(commands[i].name,tok))
3768 else if (strnequal(commands[i].name, tok, tok_len+1))
3778 else if (matches == 1)
3784 /****************************************************************************
3786 ****************************************************************************/
3792 if (next_token(NULL,buf,NULL))
3794 if ((i = process_tok(buf)) >= 0)
3795 DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));
3798 while (commands[i].description)
3800 for (j=0; commands[i].description && (j<5); j++) {
3801 DEBUG(0,("%-15s",commands[i].name));
3808 /****************************************************************************
3809 open the client sockets
3810 ****************************************************************************/
3811 static BOOL open_sockets(int port )
3813 static int last_port;
3821 if (port == 0) port=last_port;
3832 strcpy(service2,service);
3833 host = strtok(service2,"\\/");
3835 DEBUG(0,("Badly formed host name\n"));
3838 strcpy(desthost,host);
3841 DEBUG(3,("Opening sockets\n"));
3845 get_myname(myname,NULL);
3853 if ((hp = Get_Hostbyname(host))) {
3854 putip((char *)&dest_ip,(char *)hp->h_addr);
3858 /* Try and resolve the name with the netbios server */
3861 struct in_addr ip1, ip2;
3863 if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) {
3864 set_socket_options (bcast, "SO_BROADCAST");
3866 if (!got_bcast && get_myname(hs, &ip1)) {
3867 get_broadcast(&ip1, &bcast_ip, &ip2);
3870 if (name_query(bcast, host, 0x20, True, True, bcast_ip, &dest_ip,0)){
3877 DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
3883 Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
3887 DEBUG(3,("Connected\n"));
3889 set_socket_options(Client,user_socket_options);
3894 /****************************************************************************
3895 wait for keyboard activity, swallowing network packets
3896 ****************************************************************************/
3898 static char wait_keyboard(char *buffer)
3900 static void wait_keyboard(char *buffer)
3905 struct timeval timeout;
3915 FD_SET(Client,&fds);
3917 FD_SET(fileno(stdin),&fds);
3920 timeout.tv_sec = 20;
3921 timeout.tv_usec = 0;
3925 selrtn = sys_select(&fds,&timeout);
3928 if (FD_ISSET(fileno(stdin),&fds))
3936 f_flags = fcntl(fileno(stdin), F_GETFL, 0);
3937 fcntl( fileno(stdin), F_SETFL, f_flags | O_NONBLOCK);
3938 readret = read_data( fileno(stdin), &ch, 1);
3939 fcntl(fileno(stdin), F_SETFL, f_flags);
3942 if (errno != EAGAIN)
3944 /* should crash here */
3945 DEBUG(1,("readchar stdin failed\n"));
3948 else if (readret != 0)
3954 if (FD_ISSET(Client,&fds))
3955 receive_smb(Client,buffer,0);
3962 chkpath("\\",False);
3965 chkpath("\\",False);
3971 /****************************************************************************
3972 close and open the connection again
3973 ****************************************************************************/
3974 BOOL reopen_connection(char *inbuf,char *outbuf)
3976 static int open_count=0;
3980 if (open_count>5) return(False);
3982 DEBUG(1,("Trying to re-open connection\n"));
3984 set_message(outbuf,0,0,True);
3985 SCVAL(outbuf,smb_com,SMBtdis);
3986 SSVAL(outbuf,smb_tid,cnum);
3989 send_smb(Client,outbuf);
3990 receive_smb(Client,inbuf,SHORT_TIMEOUT);
3993 if (!open_sockets(0)) return(False);
3995 return(send_login(inbuf,outbuf,True,True));
3998 /****************************************************************************
3999 process commands from the client
4000 ****************************************************************************/
4001 BOOL process(char *base_directory)
4006 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4007 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4009 if ((InBuffer == NULL) || (OutBuffer == NULL))
4012 bzero(OutBuffer,smb_size);
4014 if (!send_login(InBuffer,OutBuffer,True,True))
4017 if (*base_directory) do_cd(base_directory);
4019 while (!feof(stdin))
4024 bzero(OutBuffer,smb_size);
4026 /* display a prompt */
4027 DEBUG(1,("smb: %s> ", CNV_LANG(cur_dir)));
4031 line[0] = wait_keyboard(InBuffer);
4032 /* this might not be such a good idea... */
4033 if ( line[0] == EOF)
4036 wait_keyboard(InBuffer);
4039 /* and get a response */
4041 fgets( &line[1],999, stdin);
4043 if (!fgets(line,1000,stdin))
4047 /* input language code to internal one */
4050 /* special case - first char is ! */
4057 /* and get the first part of the command */
4060 if (!next_token(&ptr,tok,NULL)) continue;
4063 if ((i = process_tok(tok)) >= 0)
4064 commands[i].fn(InBuffer,OutBuffer);
4066 DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
4068 DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
4076 /****************************************************************************
4077 usage on the program
4078 ****************************************************************************/
4079 void usage(char *pname)
4081 DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
4085 DEBUG(0,("[-t termcode] "));
4088 DEBUG(0,("\nVersion %s\n",VERSION));
4089 DEBUG(0,("\t-p port listen on the specified port\n"));
4090 DEBUG(0,("\t-d debuglevel set the debuglevel\n"));
4091 DEBUG(0,("\t-l log basename. Basename for log/debug files\n"));
4092 DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n"));
4093 DEBUG(0,("\t-N don't ask for a password\n"));
4094 DEBUG(0,("\t-P connect to service as a printer\n"));
4095 DEBUG(0,("\t-M host send a winpopup message to the host\n"));
4096 DEBUG(0,("\t-m max protocol set the max protocol level\n"));
4097 DEBUG(0,("\t-L host get a list of shares available on a host\n"));
4098 DEBUG(0,("\t-I dest IP use this IP to connect to\n"));
4099 DEBUG(0,("\t-E write messages to stderr instead of stdout\n"));
4100 DEBUG(0,("\t-U username set the network username\n"));
4101 DEBUG(0,("\t-W workgroup set the workgroup name\n"));
4103 DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
4105 DEBUG(0,("\t-T<c|x>IXgbNa command line tar\n"));
4106 DEBUG(0,("\t-D directory start from directory\n"));
4112 /****************************************************************************
4114 ****************************************************************************/
4115 int main(int argc,char *argv[])
4117 fstring base_directory;
4118 char *pname = argv[0];
4122 extern char *optarg;
4125 BOOL message = False;
4126 extern char tar_type;
4129 *base_directory = 0;
4133 setup_logging(pname,True);
4136 charset_initialise();
4147 strcpy(username,getenv("USER"));
4151 if (*username == 0 && getenv("LOGNAME"))
4153 strcpy(username,getenv("LOGNAME"));
4163 if (*argv[1] != '-')
4166 strcpy(service,argv[1]);
4170 if (count_chars(service,'\\') < 3)
4173 printf("\n%s: Not enough '\\' characters in service\n",service);
4178 if (count_chars(service,'\\') > 3)
4181 printf("\n%s: Too many '\\' characters in service\n",service);
4186 if (argc > 1 && (*argv[1] != '-'))
4189 strcpy(password,argv[1]);
4190 memset(argv[1],'X',strlen(argv[1]));
4197 setup_term_code (KANJI);
4198 while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:")) != EOF)
4200 while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:m:W:T:D:")) != EOF)
4205 max_protocol = interpret_protocol(optarg,max_protocol);
4208 strcpy(user_socket_options,optarg);
4212 strcpy(desthost,optarg);
4217 bcast_ip = *interpret_addr2(optarg);
4221 strcpy(base_directory,optarg);
4224 if (!tar_parseargs(argc, argv, optarg, optind)) {
4230 strcpy(scope,optarg);
4234 strcpy(query_host,optarg);
4239 strcpy(username,optarg);
4240 if ((p=strchr(username,'%')))
4243 strcpy(password,p+1);
4245 memset(strchr(optarg,'%')+1,'X',strlen(password));
4251 strcpy(workgroup,optarg);
4258 dest_ip = *interpret_addr2(optarg);
4259 if (zero_ip(dest_ip)) exit(1);
4264 strcpy(myname,optarg);
4270 connect_as_printer = True;
4276 DEBUGLEVEL = atoi(optarg);
4279 sprintf(debugf,"%s.client",optarg);
4282 port = atoi(optarg);
4290 if (!setup_term_code (optarg)) {
4291 DEBUG(0, ("%s: unknown terminal code name\n", optarg));
4302 if (!tar_type && !*query_host && !*service && !message)
4309 DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
4311 get_myname(*myname?NULL:myname,&myip);
4317 if (open_sockets(port)) {
4318 char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4319 char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
4322 if ((InBuffer == NULL) || (OutBuffer == NULL))
4325 bzero(OutBuffer,smb_size);
4326 if (!send_login(InBuffer,OutBuffer,True,True))
4329 if (*base_directory) do_cd(base_directory);
4331 ret=process_tar(InBuffer, OutBuffer);
4343 sprintf(service,"\\\\%s\\IPC$",query_host);
4345 connect_as_ipc = True;
4346 if (open_sockets(port))
4351 if (!send_login(NULL,NULL,True,True))
4355 if (!browse_host(True)) {
4359 if (!list_servers()) {
4374 if (open_sockets(port))
4376 pstring inbuf,outbuf;
4377 bzero(outbuf,smb_size);
4378 if (!send_session_request(inbuf,outbuf))
4381 send_message(inbuf,outbuf);
4389 if (open_sockets(port))
4391 if (!process(base_directory))
4405 /* error code stuff - put together by Merik Karman
4406 merik@blackadder.dsh.oz.au */
4415 /* Dos Error Messages */
4416 err_code_struct dos_msgs[] = {
4417 {"ERRbadfunc",1,"Invalid function."},
4418 {"ERRbadfile",2,"File not found."},
4419 {"ERRbadpath",3,"Directory invalid."},
4420 {"ERRnofids",4,"No file descriptors available"},
4421 {"ERRnoaccess",5,"Access denied."},
4422 {"ERRbadfid",6,"Invalid file handle."},
4423 {"ERRbadmcb",7,"Memory control blocks destroyed."},
4424 {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
4425 {"ERRbadmem",9,"Invalid memory block address."},
4426 {"ERRbadenv",10,"Invalid environment."},
4427 {"ERRbadformat",11,"Invalid format."},
4428 {"ERRbadaccess",12,"Invalid open mode."},
4429 {"ERRbaddata",13,"Invalid data."},
4430 {"ERR",14,"reserved."},
4431 {"ERRbaddrive",15,"Invalid drive specified."},
4432 {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
4433 {"ERRdiffdevice",17,"Not same device."},
4434 {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
4435 {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
4436 {"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."},
4437 {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
4438 {"ERRbadpipe",230,"Pipe invalid."},
4439 {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
4440 {"ERRpipeclosing",232,"Pipe close in progress."},
4441 {"ERRnotconnected",233,"No process on other end of pipe."},
4442 {"ERRmoredata",234,"There is more data to be returned."},
4443 {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
4446 /* Server Error Messages */
4447 err_code_struct server_msgs[] = {
4448 {"ERRerror",1,"Non-specific error code."},
4449 {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
4450 {"ERRbadtype",3,"reserved."},
4451 {"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."},
4452 {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
4453 {"ERRinvnetname",6,"Invalid network name in tree connect."},
4454 {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."},
4455 {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
4456 {"ERRqtoobig",50,"Print queue full -- no space."},
4457 {"ERRqeof",51,"EOF on print queue dump."},
4458 {"ERRinvpfid",52,"Invalid print file FID."},
4459 {"ERRsmbcmd",64,"The server did not recognize the command received."},
4460 {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
4461 {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."},
4462 {"ERRreserved",68,"reserved."},
4463 {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."},
4464 {"ERRreserved",70,"reserved."},
4465 {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
4466 {"ERRpaused",81,"Server is paused."},
4467 {"ERRmsgoff",82,"Not receiving messages."},
4468 {"ERRnoroom",83,"No room to buffer message."},
4469 {"ERRrmuns",87,"Too many remote user names."},
4470 {"ERRtimeout",88,"Operation timed out."},
4471 {"ERRnoresource",89,"No resources currently available for request."},
4472 {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
4473 {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
4474 {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
4475 {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
4476 {"ERRcontmpx",252,"Continue in MPX mode."},
4477 {"ERRreserved",253,"reserved."},
4478 {"ERRreserved",254,"reserved."},
4479 {"ERRnosupport",0xFFFF,"Function not supported."},
4482 /* Hard Error Messages */
4483 err_code_struct hard_msgs[] = {
4484 {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
4485 {"ERRbadunit",20,"Unknown unit."},
4486 {"ERRnotready",21,"Drive not ready."},
4487 {"ERRbadcmd",22,"Unknown command."},
4488 {"ERRdata",23,"Data error (CRC)."},
4489 {"ERRbadreq",24,"Bad request structure length."},
4490 {"ERRseek",25 ,"Seek error."},
4491 {"ERRbadmedia",26,"Unknown media type."},
4492 {"ERRbadsector",27,"Sector not found."},
4493 {"ERRnopaper",28,"Printer out of paper."},
4494 {"ERRwrite",29,"Write fault."},
4495 {"ERRread",30,"Read fault."},
4496 {"ERRgeneral",31,"General failure."},
4497 {"ERRbadshare",32,"A open conflicts with an existing open."},
4498 {"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."},
4499 {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
4500 {"ERRFCBUnavail",35,"No FCBs are available to process request."},
4501 {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
4509 err_code_struct *err_msgs;
4512 {0x01,"ERRDOS",dos_msgs},
4513 {0x02,"ERRSRV",server_msgs},
4514 {0x03,"ERRHRD",hard_msgs},
4515 {0x04,"ERRXOS",NULL},
4516 {0xE1,"ERRRMX1",NULL},
4517 {0xE2,"ERRRMX2",NULL},
4518 {0xE3,"ERRRMX3",NULL},
4519 {0xFF,"ERRCMD",NULL},
4523 /****************************************************************************
4524 return a SMB error string from a SMB buffer
4525 ****************************************************************************/
4526 char *smb_errstr(char *inbuf)
4529 int class = CVAL(inbuf,smb_rcls);
4530 int num = SVAL(inbuf,smb_err);
4533 for (i=0;err_classes[i].class;i++)
4534 if (err_classes[i].code == class)
4536 if (err_classes[i].err_msgs)
4538 err_code_struct *err = err_classes[i].err_msgs;
4539 for (j=0;err[j].name;j++)
4540 if (num == err[j].code)
4543 sprintf(ret,"%s - %s (%s)",err_classes[i].class,
4544 err[j].name,err[j].message);
4546 sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
4551 sprintf(ret,"%s - %d",err_classes[i].class,num);
4555 sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);