diff options
Diffstat (limited to 'source/client/client.c')
-rw-r--r-- | source/client/client.c | 1071 |
1 files changed, 645 insertions, 426 deletions
diff --git a/source/client/client.c b/source/client/client.c index 504cb5a0bb4..6bd94be7569 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -24,7 +24,6 @@ #endif #include "includes.h" -#include "nameserv.h" #ifndef REGISTER #define REGISTER 0 @@ -34,15 +33,15 @@ pstring cur_dir = "\\"; pstring cd_path = ""; pstring service=""; pstring desthost=""; -pstring myname = ""; +extern pstring myname; pstring password = ""; pstring username=""; pstring workgroup=WORKGROUP; +char *cmdstr=""; BOOL got_pass = False; BOOL connect_as_printer = False; BOOL connect_as_ipc = False; -extern struct in_addr bcast_ip; -static BOOL got_bcast=False; +extern struct in_addr ipzero; char cryptkey[8]; BOOL doencrypt=False; @@ -64,23 +63,34 @@ int max_protocol = PROTOCOL_NT1; time_t newer_than = 0; int archive_level = 0; -extern struct in_addr myip; - extern pstring debugf; extern int DEBUGLEVEL; BOOL translation = False; + +static BOOL send_trans_request(char *outbuf,int trans, + char *name,int fid,int flags, + char *data,char *param,uint16 *setup, + int ldata,int lparam,int lsetup, + int mdata,int mparam,int msetup); +static BOOL receive_trans_response(char *inbuf,int trans, + int *data_len,int *param_len, + char **data,char **param); +static int interpret_long_filename(int level,char *p,file_info *finfo); +static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir); +static int interpret_short_filename(char *p,file_info *finfo); +static BOOL call_api(int prcnt,int drcnt, + int mprcnt,int mdrcnt, + int *rprcnt,int *rdrcnt, + char *param,char *data, + char **rparam,char **rdata); + + /* clitar bits insert */ -extern void cmd_tar(); -extern void cmd_block(); -extern void cmd_tarmode(); -extern void cmd_setmode(); extern int blocksize; extern BOOL tar_inc; extern BOOL tar_reset; -extern int process_tar(); -extern int tar_parseargs(); /* clitar bits end */ @@ -150,20 +160,6 @@ setup_term_code (char *code) #define CNV_INPUT(s) unix2dos_format(s,True) #endif -static void send_logout(void ); -BOOL reopen_connection(char *inbuf,char *outbuf); -static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir); -static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir); -static BOOL call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt, - int *rprcnt,int *rdrcnt,char *param,char *data, - char **rparam,char **rdata); -static BOOL send_trans_request(char *outbuf,int trans, - char *name,int fid,int flags, - char *data,char *param,uint16 *setup, - int ldata,int lparam,int lsetup, - int mdata,int mparam,int msetup); - - /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ @@ -482,9 +478,322 @@ static void display_finfo(file_info *finfo) CNV_LANG(finfo->name), attrib_string(finfo->mode), finfo->size, - asctime(LocalTime(&t,GMT_TO_LOCAL)))); + asctime(LocalTime(&t)))); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found. Use the TRANSACT2 + call for long filenames + ****************************************************************************/ +static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir) +{ + int max_matches = 512; + int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */ + char *p; + pstring mask; + file_info finfo; + int i; + char *dirlist = NULL; + int dirlist_len = 0; + int total_received = 0; + BOOL First = True; + char *resp_data=NULL; + char *resp_param=NULL; + int resp_data_len = 0; + int resp_param_len=0; + + int ff_resume_key = 0; + int ff_searchcount=0; + int ff_eos=0; + int ff_lastname=0; + int ff_dir_handle=0; + int loop_count = 0; + + uint16 setup; + pstring param; + + strcpy(mask,Mask); + + while (ff_eos == 0) + { + loop_count++; + if (loop_count > 200) + { + DEBUG(0,("ERROR: Looping in FIND_NEXT??\n")); + break; + } + + if (First) + { + setup = TRANSACT2_FINDFIRST; + SSVAL(param,0,attribute); /* attribute */ + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,8+4+2); /* resume required + close on end + continue */ + SSVAL(param,6,info_level); + SIVAL(param,8,0); + strcpy(param+12,mask); + } + else + { + setup = TRANSACT2_FINDNEXT; + SSVAL(param,0,ff_dir_handle); + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,info_level); + SIVAL(param,6,ff_resume_key); /* ff_resume_key */ + SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ + strcpy(param+12,mask); + + DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", + ff_dir_handle,ff_resume_key,ff_lastname,mask)); + } + /* ??? original code added 1 pad byte after param */ + + send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0, + NULL,param,&setup, + 0,12+strlen(mask)+1,1, + BUFFER_SIZE,10,0); + + if (!receive_trans_response(inbuf,SMBtrans2, + &resp_data_len,&resp_param_len, + &resp_data,&resp_param)) + { + DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf))); + break; + } + + /* parse out some important return info */ + p = resp_param; + if (First) + { + ff_dir_handle = SVAL(p,0); + ff_searchcount = SVAL(p,2); + ff_eos = SVAL(p,4); + ff_lastname = SVAL(p,8); + } + else + { + ff_searchcount = SVAL(p,0); + ff_eos = SVAL(p,2); + ff_lastname = SVAL(p,6); + } + + if (ff_searchcount == 0) + break; + + /* point to the data bytes */ + p = resp_data; + + /* we might need the lastname for continuations */ + if (ff_lastname > 0) + { + switch(info_level) + { + case 260: + ff_resume_key =0; + StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname); + /* strcpy(mask,p+ff_lastname+94); */ + break; + case 1: + strcpy(mask,p + ff_lastname + 1); + ff_resume_key = 0; + break; + } + } + else + strcpy(mask,""); + + /* and add them to the dirlist pool */ + dirlist = Realloc(dirlist,dirlist_len + resp_data_len); + + if (!dirlist) + { + DEBUG(0,("Failed to expand dirlist\n")); + break; + } + + /* put in a length for the last entry, to ensure we can chain entries + into the next packet */ + { + char *p2; + for (p2=p,i=0;i<(ff_searchcount-1);i++) + p2 += interpret_long_filename(info_level,p2,NULL); + SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p)); + } + + /* grab the data for later use */ + memcpy(dirlist+dirlist_len,p,resp_data_len); + dirlist_len += resp_data_len; + + total_received += ff_searchcount; + + if (resp_data) free(resp_data); resp_data = NULL; + if (resp_param) free(resp_param); resp_param = NULL; + + DEBUG(3,("received %d entries (eos=%d resume=%d)\n", + ff_searchcount,ff_eos,ff_resume_key)); + + First = False; + } + + if (!fn) + for (p=dirlist,i=0;i<total_received;i++) + { + p += interpret_long_filename(info_level,p,&finfo); + display_finfo(&finfo); + } + + for (p=dirlist,i=0;i<total_received;i++) + { + p += interpret_long_filename(info_level,p,&finfo); + dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True); + } + + /* free up the dirlist buffer */ + if (dirlist) free(dirlist); + return(total_received); } + +/**************************************************************************** + do a directory listing, calling fn on each file found + ****************************************************************************/ +static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir) +{ + char *p; + int received = 0; + BOOL first = True; + char status[21]; + int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE; + int num_received = 0; + int i; + char *dirlist = NULL; + pstring mask; + file_info finfo; + + finfo = def_finfo; + + bzero(status,21); + + strcpy(mask,Mask); + + while (1) + { + bzero(outbuf,smb_size); + if (first) + set_message(outbuf,2,5 + strlen(mask),True); + else + set_message(outbuf,2,5 + 21,True); + +#if FFIRST + if (Protocol >= PROTOCOL_LANMAN1) + CVAL(outbuf,smb_com) = SMBffirst; + else +#endif + CVAL(outbuf,smb_com) = SMBsearch; + + SSVAL(outbuf,smb_tid,cnum); + setup_pkt(outbuf); + + SSVAL(outbuf,smb_vwv0,num_asked); + SSVAL(outbuf,smb_vwv1,attribute); + + p = smb_buf(outbuf); + *p++ = 4; + + if (first) + strcpy(p,mask); + else + strcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + if (first) + SSVAL(p,0,0); + else + { + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + } + + send_smb(Client,outbuf); + receive_smb(Client,inbuf,CLIENT_TIMEOUT); + + received = SVAL(inbuf,smb_vwv0); + + DEBUG(5,("dir received %d\n",received)); + + DEBUG(6,("errstr=%s\n",smb_errstr(inbuf))); + + if (received <= 0) break; + + first = False; + + dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + + if (!dirlist) + return 0; + + p = smb_buf(inbuf) + 3; + + memcpy(dirlist+num_received*DIR_STRUCT_SIZE, + p,received*DIR_STRUCT_SIZE); + + memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); + + num_received += received; + + if (CVAL(inbuf,smb_rcls) != 0) break; + } + +#if FFIRST + if (!first && Protocol >= PROTOCOL_LANMAN1) + { + bzero(outbuf,smb_size); + CVAL(outbuf,smb_com) = SMBfclose; + + SSVAL(outbuf,smb_tid,cnum); + setup_pkt(outbuf); + + p = smb_buf(outbuf); + *p++ = 4; + + strcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + + send_smb(Client,outbuf); + receive_smb(Client,inbuf,CLIENT_TIMEOUT); + + if (CVAL(inbuf,smb_rcls) != 0) + DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf))); + } +#endif + + if (!fn) + for (p=dirlist,i=0;i<num_received;i++) + { + p += interpret_short_filename(p,&finfo); + display_finfo(&finfo); + } + + for (p=dirlist,i=0;i<num_received;i++) + { + p += interpret_short_filename(p,&finfo); + dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False); + } + + if (dirlist) free(dirlist); + return(num_received); +} + + + /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ @@ -518,6 +827,34 @@ static BOOL do_this_one(file_info *finfo) return(True); } + +/***************************************************************************** + Convert a character pointer in a call_api() response to a form we can use. + This function contains code to prevent core dumps if the server returns + invalid data. +*****************************************************************************/ +static char *fix_char_ptr(unsigned int datap, unsigned int converter, char *rdata, int rdrcnt) +{ +if( datap == 0 ) /* turn NULL pointers */ + { /* into zero length strings */ + return ""; + } +else + { + unsigned int offset = datap - converter; + + if( offset < 0 || offset >= rdrcnt ) + { + DEBUG(1,("bad char ptr: datap=%u, converter=%u, rdata=%u, rdrcnt=%d>", datap, converter, (unsigned)rdata, rdrcnt)); + return "<ERROR>"; + } + else + { + return &rdata[offset]; + } + } +} + /**************************************************************************** interpret a short filename structure The length of the structure is returned @@ -684,148 +1021,11 @@ static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,B /**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ -static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir) -{ - char *p; - int received = 0; - BOOL first = True; - char status[21]; - int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE; - int num_received = 0; - int i; - char *dirlist = NULL; - pstring mask; - file_info finfo; - - finfo = def_finfo; - - bzero(status,21); - - strcpy(mask,Mask); - - while (1) - { - bzero(outbuf,smb_size); - if (first) - set_message(outbuf,2,5 + strlen(mask),True); - else - set_message(outbuf,2,5 + 21,True); - -#if FFIRST - if (Protocol >= PROTOCOL_LANMAN1) - CVAL(outbuf,smb_com) = SMBffirst; - else -#endif - CVAL(outbuf,smb_com) = SMBsearch; - - SSVAL(outbuf,smb_tid,cnum); - setup_pkt(outbuf); - - SSVAL(outbuf,smb_vwv0,num_asked); - SSVAL(outbuf,smb_vwv1,attribute); - - p = smb_buf(outbuf); - *p++ = 4; - - if (first) - strcpy(p,mask); - else - strcpy(p,""); - p += strlen(p) + 1; - - *p++ = 5; - if (first) - SSVAL(p,0,0); - else - { - SSVAL(p,0,21); - p += 2; - memcpy(p,status,21); - } - - send_smb(Client,outbuf); - receive_smb(Client,inbuf,CLIENT_TIMEOUT); - - received = SVAL(inbuf,smb_vwv0); - - DEBUG(5,("dir received %d\n",received)); - - DEBUG(6,("errstr=%s\n",smb_errstr(inbuf))); - - if (received <= 0) break; - - first = False; - - dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); - - if (!dirlist) - return 0; - - p = smb_buf(inbuf) + 3; - - memcpy(dirlist+num_received*DIR_STRUCT_SIZE, - p,received*DIR_STRUCT_SIZE); - - memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); - - num_received += received; - - if (CVAL(inbuf,smb_rcls) != 0) break; - } - -#if FFIRST - if (!first && Protocol >= PROTOCOL_LANMAN1) - { - bzero(outbuf,smb_size); - CVAL(outbuf,smb_com) = SMBfclose; - - SSVAL(outbuf,smb_tid,cnum); - setup_pkt(outbuf); - - p = smb_buf(outbuf); - *p++ = 4; - - strcpy(p,""); - p += strlen(p) + 1; - - *p++ = 5; - SSVAL(p,0,21); - p += 2; - memcpy(p,status,21); - - send_smb(Client,outbuf); - receive_smb(Client,inbuf,CLIENT_TIMEOUT,False); - - if (CVAL(inbuf,smb_rcls) != 0) - DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf))); - } -#endif - - if (!fn) - for (p=dirlist,i=0;i<num_received;i++) - { - p += interpret_short_filename(p,&finfo); - display_finfo(&finfo); - } - - for (p=dirlist,i=0;i<num_received;i++) - { - p += interpret_short_filename(p,&finfo); - dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False); - } - - if (dirlist) free(dirlist); - return(num_received); -} - -/**************************************************************************** receive a SMB trans or trans2 response allocating the necessary memory ****************************************************************************/ static BOOL receive_trans_response(char *inbuf,int trans, int *data_len,int *param_len, - char **data,char **param) + char **data,char **param) { int total_data=0; int total_param=0; @@ -893,178 +1093,6 @@ static BOOL receive_trans_response(char *inbuf,int trans, return(True); } -/**************************************************************************** - do a directory listing, calling fn on each file found. Use the TRANSACT2 - call for long filenames - ****************************************************************************/ -static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir) -{ - int max_matches = 512; - int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */ - char *p; - pstring mask; - file_info finfo; - int i; - char *dirlist = NULL; - int dirlist_len = 0; - int total_received = 0; - BOOL First = True; - char *resp_data=NULL; - char *resp_param=NULL; - int resp_data_len = 0; - int resp_param_len=0; - - int ff_resume_key = 0; - int ff_searchcount=0; - int ff_eos=0; - int ff_lastname=0; - int ff_dir_handle=0; - int loop_count = 0; - - uint16 setup; - pstring param; - - strcpy(mask,Mask); - - while (ff_eos == 0) - { - loop_count++; - if (loop_count > 200) - { - DEBUG(0,("ERROR: Looping in FIND_NEXT??\n")); - break; - } - - if (First) - { - setup = TRANSACT2_FINDFIRST; - SSVAL(param,0,attribute); /* attribute */ - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,8+4+2); /* resume required + close on end + continue */ - SSVAL(param,6,info_level); - SIVAL(param,8,0); - strcpy(param+12,mask); - } - else - { - setup = TRANSACT2_FINDNEXT; - SSVAL(param,0,ff_dir_handle); - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,info_level); - SIVAL(param,6,ff_resume_key); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ - strcpy(param+12,mask); - - DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_resume_key,ff_lastname,mask)); - } - /* ??? original code added 1 pad byte after param */ - - send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0, - NULL,param,&setup, - 0,12+strlen(mask)+1,1, - BUFFER_SIZE,10,0); - - if (!receive_trans_response(inbuf,SMBtrans2, - &resp_data_len,&resp_param_len, - &resp_data,&resp_param)) - { - DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf))); - break; - } - - /* parse out some important return info */ - p = resp_param; - if (First) - { - ff_dir_handle = SVAL(p,0); - ff_searchcount = SVAL(p,2); - ff_eos = SVAL(p,4); - ff_lastname = SVAL(p,8); - } - else - { - ff_searchcount = SVAL(p,0); - ff_eos = SVAL(p,2); - ff_lastname = SVAL(p,6); - } - - if (ff_searchcount == 0) - break; - - /* point to the data bytes */ - p = resp_data; - - /* we might need the lastname for continuations */ - if (ff_lastname > 0) - { - switch(info_level) - { - case 260: - ff_resume_key =0; - StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname); - /* strcpy(mask,p+ff_lastname+94); */ - break; - case 1: - strcpy(mask,p + ff_lastname + 1); - ff_resume_key = 0; - break; - } - } - else - strcpy(mask,""); - - /* and add them to the dirlist pool */ - dirlist = Realloc(dirlist,dirlist_len + resp_data_len); - - if (!dirlist) - { - DEBUG(0,("Failed to expand dirlist\n")); - break; - } - - /* put in a length for the last entry, to ensure we can chain entries - into the next packet */ - { - char *p2; - for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(info_level,p2,NULL); - SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p)); - } - - /* grab the data for later use */ - memcpy(dirlist+dirlist_len,p,resp_data_len); - dirlist_len += resp_data_len; - - total_received += ff_searchcount; - - if (resp_data) free(resp_data); resp_data = NULL; - if (resp_param) free(resp_param); resp_param = NULL; - - DEBUG(3,("received %d entries (eos=%d resume=%d)\n", - ff_searchcount,ff_eos,ff_resume_key)); - - First = False; - } - - if (!fn) - for (p=dirlist,i=0;i<total_received;i++) - { - p += interpret_long_filename(info_level,p,&finfo); - display_finfo(&finfo); - } - - for (p=dirlist,i=0;i<total_received;i++) - { - p += interpret_long_filename(info_level,p,&finfo); - dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True); - } - - /* free up the dirlist buffer */ - if (dirlist) free(dirlist); - return(total_received); -} - /**************************************************************************** get a directory listing @@ -2131,13 +2159,12 @@ static void cmd_mput(void) strcpy(rname,cur_dir); strcat(rname,lname); - if (!do_mkdir(rname)) - { - strcat(lname,"/"); - if (!seek_list(f,lname)) - break; - goto again1; - } + if (!chkpath(rname,False) && !do_mkdir(rname)) { + strcat(lname,"/"); + if (!seek_list(f,lname)) + break; + goto again1; + } continue; } @@ -2178,7 +2205,7 @@ static void do_cancel(int job) bzero(param,sizeof(param)); p = param; - SSVAL(p,0,81); /* api number */ + SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; strcpy(p,"W"); p = skip_string(p,1); @@ -2425,7 +2452,7 @@ static void cmd_print(char *inbuf,char *outbuf ) } /**************************************************************************** -print a file +show a print queue ****************************************************************************/ static void cmd_queue(char *inbuf,char *outbuf ) { @@ -2487,6 +2514,109 @@ static void cmd_queue(char *inbuf,char *outbuf ) /**************************************************************************** +show information about a print queue +****************************************************************************/ +static void cmd_qinfo(char *inbuf,char *outbuf ) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + int result_code=0; + + bzero(param,sizeof(param)); + + p = param; + SSVAL(p,0,70); /* API function number 70 (DosPrintQGetInfo) */ + p += 2; + strcpy(p,"zWrLh"); /* parameter description? */ + p = skip_string(p,1); + strcpy(p,"zWWWWzzzzWWzzl"); /* returned data format */ + p = skip_string(p,1); + strcpy(p,strrchr(service,'\\')+1); /* name of queue */ + p = skip_string(p,1); + SSVAL(p,0,3); /* API function level 3, just queue info, no job info */ + SSVAL(p,2,1000); /* size of bytes of returned data buffer */ + p += 4; + strcpy(p,""); /* subformat */ + p = skip_string(p,1); + + DEBUG(1,("Calling DosPrintQueueGetInfo()...\n")); + if( call_api(PTR_DIFF(p,param), 0, + 10, 4096, + &rprcnt, &rdrcnt, + param, NULL, + &rparam, &rdata) ) + { + int converter; + result_code = SVAL(rparam,0); + converter = SVAL(rparam,2); /* conversion factor */ + + DEBUG(2,("returned %d bytes of parameters, %d bytes of data, %d records\n", rprcnt, rdrcnt, SVAL(rparam,4) )); + + if (result_code == 0) /* if no error, */ + { + p = rdata; /* received data */ + + printf("Name: \"%s\"\n", fix_char_ptr(SVAL(p,0), converter, rdata, rdrcnt) ); + printf("Priority: %u\n", SVAL(p,4) ); + printf("Start time: %u\n", SVAL(p,6) ); + printf("Until time: %u\n", SVAL(p,8) ); + printf("Seperator file: \"%s\"\n", fix_char_ptr(SVAL(p,12), converter, rdata, rdrcnt) ); + printf("Print processor: \"%s\"\n", fix_char_ptr(SVAL(p,16), converter, rdata, rdrcnt) ); + printf("Parameters: \"%s\"\n", fix_char_ptr(SVAL(p,20), converter, rdata, rdrcnt) ); + printf("Comment: \"%s\"\n", fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt) ); + printf("Status: %u\n", SVAL(p,28) ); + printf("Jobs: %u\n", SVAL(p,30) ); + printf("Printers: \"%s\"\n", fix_char_ptr(SVAL(p,32), converter, rdata, rdrcnt) ); + printf("Drivername: \"%s\"\n", fix_char_ptr(SVAL(p,36), converter, rdata, rdrcnt) ); + + /* Dump the driver data */ + { + int count, x, y, c; + char *ddptr; + + ddptr = rdata + SVAL(p,40) - converter; + if( SVAL(p,40) == 0 ) {count = 0;} else {count = IVAL(ddptr,0);} + printf("Driverdata: size=%d, version=%u\n", count, IVAL(ddptr,4) ); + + for(x=8; x < count; x+=16) + { + for(y=0; y < 16; y++) + { + if( (x+y) < count ) + printf("%2.2X ", CVAL(ddptr,(x+y)) ); + else + fputs(" ", stdout); + } + for(y=0; y < 16 && (x+y) < count; y++) + { + c = CVAL(ddptr,(x+y)); + if(isprint(c)) + fputc(c, stdout); + else + fputc('.', stdout); + } + fputc('\n', stdout); + } + } + + } + } + else /* call_api() failed */ + { + printf("Failed, error = %d\n", result_code); + } + + /* If any parameters or data were returned, free the storage. */ + if(rparam) free(rparam); + if(rdata) free(rdata); + + return; +} + +/**************************************************************************** delete some files ****************************************************************************/ static void do_del(file_info *finfo) @@ -2670,7 +2800,7 @@ static void cmd_newer(void) { newer_than = sbuf.st_mtime; DEBUG(1,("Getting files newer than %s", - asctime(LocalTime(&newer_than,GMT_TO_LOCAL)))); + asctime(LocalTime(&newer_than)))); } else newer_than = 0; @@ -2875,6 +3005,21 @@ static BOOL send_session_request(char *inbuf,char *outbuf) return(True); } +static struct { + int prot; + char *name; +} prots[] = { + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LM 0.12"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {-1,NULL} +}; + /**************************************************************************** send a login command @@ -2888,26 +3033,11 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu int sec_mode=0; int crypt_len; int max_vcs=0; - struct { - int prot; - char *name; - } - prots[] = - { - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, - {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {-1,NULL} - }; char *pass = NULL; pstring dev; char *p; int numprots; + int tries=0; if (was_null) { @@ -3032,7 +3162,7 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu static BOOL done_time = False; if (!done_time) { DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n", - asctime(LocalTime(&servertime,GMT_TO_LOCAL)), + asctime(LocalTime(&servertime)), -(double)(serverzone/3600.0))); done_time = True; } @@ -3045,6 +3175,10 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu else pass = (char *)getpass("Password: "); + /* use a blank username for the 2nd try with a blank password */ + if (tries++ && !*pass) + *username = 0; + if (Protocol >= PROTOCOL_LANMAN1 && use_setup) { fstring pword; @@ -3182,19 +3316,36 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu strcpy(pword, ""); passlen=1; } - set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True); - CVAL(outbuf,smb_com) = SMBtconX; - setup_pkt(outbuf); - - SSVAL(outbuf,smb_vwv0,0xFF); - SSVAL(outbuf,smb_vwv3,passlen); + if (Protocol <= PROTOCOL_CORE) { + set_message(outbuf,0,6 + strlen(service) + passlen + strlen(dev),True); + CVAL(outbuf,smb_com) = SMBtcon; + setup_pkt(outbuf); - p = smb_buf(outbuf); - memcpy(p,pword,passlen); - p += passlen; - strcpy(p,service); - p = skip_string(p,1); - strcpy(p,dev); + p = smb_buf(outbuf); + *p++ = 0x04; + strcpy(p, service); + p = skip_string(p,1); + *p++ = 0x04; + memcpy(p,pword,passlen); + p += passlen; + *p++ = 0x04; + strcpy(p, dev); + } + else { + set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True); + CVAL(outbuf,smb_com) = SMBtconX; + setup_pkt(outbuf); + + SSVAL(outbuf,smb_vwv0,0xFF); + SSVAL(outbuf,smb_vwv3,passlen); + + p = smb_buf(outbuf); + memcpy(p,pword,passlen); + p += passlen; + strcpy(p,service); + p = skip_string(p,1); + strcpy(p,dev); + } } send_smb(Client,outbuf); @@ -3225,11 +3376,18 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu } - max_xmit = MIN(max_xmit,BUFFER_SIZE-4); - if (max_xmit <= 0) - max_xmit = BUFFER_SIZE - 4; + if (Protocol <= PROTOCOL_CORE) { + max_xmit = SVAL(inbuf,smb_vwv0); + + cnum = SVAL(inbuf,smb_vwv1); + } + else { + max_xmit = MIN(max_xmit,BUFFER_SIZE-4); + if (max_xmit <= 0) + max_xmit = BUFFER_SIZE - 4; - cnum = SVAL(inbuf,smb_tid); + cnum = SVAL(inbuf,smb_tid); + } DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit)); @@ -3522,7 +3680,7 @@ static void server_info() bzero(param,sizeof(param)); p = param; - SSVAL(p,0,63); /* api number */ + SSVAL(p,0,63); /* NetServerGetInfo()? */ p += 2; strcpy(p,"WrLh"); p = skip_string(p,1); @@ -3563,34 +3721,49 @@ static void server_info() /**************************************************************************** try and browse available connections on a host ****************************************************************************/ -static BOOL list_servers() +static BOOL list_servers(char *wk_grp) { char *rparam = NULL; char *rdata = NULL; int rdrcnt,rprcnt; - char *p; + char *p,*svtype_p; pstring param; int uLevel = 1; int count = 0; + BOOL ok = False; + BOOL generic_request = False; + + + if (strequal(wk_grp,"WORKGROUP")) { + /* we won't specify a workgroup */ + generic_request = True; + } /* now send a SMBtrans command with api ServerEnum? */ p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - strcpy(p,"WrLehDO"); + + strcpy(p,generic_request?"WrLehDO":"WrLehDz"); p = skip_string(p,1); strcpy(p,"B16BBDz"); -#if 0 - strcpy(p,getenv("XX_STR2")); -#endif p = skip_string(p,1); SSVAL(p,0,uLevel); SSVAL(p,2,0x2000); /* buf length */ p += 4; - SIVAL(p,0,SV_TYPE_ALL); + svtype_p = p; + p += 4; + + if (!generic_request) { + strcpy(p, wk_grp); + p = skip_string(p,1); + } + + /* first ask for a list of servers in this workgroup */ + SIVAL(svtype_p,0,SV_TYPE_ALL); if (call_api(PTR_DIFF(p+4,param),0, 8,10000, @@ -3618,7 +3791,8 @@ static BOOL list_servers() printf("\t%-16.16s %s\n", sname, comment_offset?rdata+comment_offset-converter:""); - + + ok=True; p2 += 26; } } @@ -3627,7 +3801,8 @@ static BOOL list_servers() if (rparam) {free(rparam); rparam = NULL;} if (rdata) {free(rdata); rdata = NULL;} - SIVAL(p,0,SV_TYPE_DOMAIN_ENUM); + /* now ask for a list of workgroups */ + SIVAL(svtype_p,0,SV_TYPE_DOMAIN_ENUM); if (call_api(PTR_DIFF(p+4,param),0, 8,10000, @@ -3656,6 +3831,7 @@ static BOOL list_servers() sname, comment_offset?rdata+comment_offset-converter:""); + ok=True; p2 += 26; } } @@ -3664,14 +3840,10 @@ static BOOL list_servers() if (rparam) free(rparam); if (rdata) free(rdata); - return(count>0); + return(ok); } - - -void cmd_help(); - /* This defines the commands supported by this client */ struct { @@ -3705,6 +3877,7 @@ struct {"print",cmd_print,"<file name> print a file"}, {"printmode",cmd_printmode,"<graphics or text> set the print mode"}, {"queue",cmd_queue,"show the print queue"}, + {"qinfo",cmd_qinfo,"show print queue information"}, {"cancel",cmd_cancel,"<jobid> cancel a print queue entry"}, {"stat",cmd_stat,"<file> get info on a file (experimental!)"}, {"quit",send_logout,"logoff the server"}, @@ -3815,13 +3988,12 @@ static BOOL open_sockets(int port ) strcpy(desthost,host); } - DEBUG(3,("Opening sockets\n")); - - if (*myname == 0) - { + if (*myname == 0) { get_myname(myname,NULL); - strupper(myname); - } + } + strupper(myname); + + DEBUG(3,("Opening sockets\n")); if (!have_ip) { @@ -3834,17 +4006,13 @@ static BOOL open_sockets(int port ) #ifdef USENMB /* Try and resolve the name with the netbios server */ int bcast; - pstring hs; - struct in_addr ip1, ip2; - - if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) { - set_socket_options (bcast, "SO_BROADCAST"); - if (!got_bcast && get_myname(hs, &ip1)) { - get_broadcast(&ip1, &bcast_ip, &ip2); - } + if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()))) != -1) { + set_socket_options(bcast, "SO_BROADCAST"); - if (name_query(bcast, host, 0x20, True, True, bcast_ip, &dest_ip,0)){ + if (name_query(bcast, host, 0x20, True, True, *iface_bcast(dest_ip), + &dest_ip,0)) { failed = False; } close (bcast); @@ -3975,10 +4143,11 @@ BOOL reopen_connection(char *inbuf,char *outbuf) /**************************************************************************** process commands from the client ****************************************************************************/ -BOOL process(char *base_directory) +static BOOL process(char *base_directory) { extern FILE *dbf; pstring line; + char *cmd; char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); @@ -3993,7 +4162,44 @@ BOOL process(char *base_directory) if (*base_directory) do_cd(base_directory); - while (!feof(stdin)) + cmd = cmdstr; + if (cmd[0] != '\0') while (cmd[0] != '\0') + { + char *p; + fstring tok; + int i; + + if ((p = strchr(cmd, ';')) == 0) + { + strncpy(line, cmd, 999); + line[1000] = '\0'; + cmd += strlen(cmd); + } + else + { + if (p - cmd > 999) p = cmd + 999; + strncpy(line, cmd, p - cmd); + line[p - cmd] = '\0'; + cmd = p + 1; + } + + /* input language code to internal one */ + CNV_INPUT (line); + + /* and get the first part of the command */ + { + char *ptr = line; + if (!next_token(&ptr,tok,NULL)) continue; + } + + if ((i = process_tok(tok)) >= 0) + commands[i].fn(InBuffer,OutBuffer); + else if (i == -2) + DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok))); + else + DEBUG(0,("%s: command not found\n",CNV_LANG(tok))); + } + else while (!feof(stdin)) { fstring tok; int i; @@ -4053,7 +4259,7 @@ BOOL process(char *base_directory) /**************************************************************************** usage on the program ****************************************************************************/ -void usage(char *pname) +static void usage(char *pname) { DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ", pname)); @@ -4076,6 +4282,7 @@ void usage(char *pname) DEBUG(0,("\t-E write messages to stderr instead of stdout\n")); DEBUG(0,("\t-U username set the network username\n")); DEBUG(0,("\t-W workgroup set the workgroup name\n")); + DEBUG(0,("\t-c command string execute semicolon separated commands\n")); #ifdef KANJI DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n")); #endif /* KANJI */ @@ -4089,11 +4296,11 @@ void usage(char *pname) /**************************************************************************** main program ****************************************************************************/ -int main(int argc,char *argv[]) + int main(int argc,char *argv[]) { fstring base_directory; char *pname = argv[0]; - int port = 139; + int port = SMB_PORT; int opt; extern FILE *dbf; extern char *optarg; @@ -4101,6 +4308,7 @@ int main(int argc,char *argv[]) pstring query_host; BOOL message = False; extern char tar_type; + static pstring servicesf = CONFIGFILE; *query_host = 0; *base_directory = 0; @@ -4172,10 +4380,9 @@ int main(int argc,char *argv[]) #ifdef KANJI setup_term_code (KANJI); - while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:")) != EOF) -#else - while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:m:W:T:D:")) != EOF) -#endif /* KANJI */ +#endif + while ((opt = + getopt(argc, argv,"s:B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF) switch (opt) { case 'm': @@ -4191,8 +4398,7 @@ int main(int argc,char *argv[]) message = True; break; case 'B': - bcast_ip = *interpret_addr2(optarg); - got_bcast = True; + iface_set_default(NULL,optarg,NULL); break; case 'D': strcpy(base_directory,optarg); @@ -4258,19 +4464,26 @@ int main(int argc,char *argv[]) case 'p': port = atoi(optarg); break; + case 'c': + cmdstr = optarg; + got_pass = True; + break; case 'h': usage(pname); exit(0); break; -#ifdef KANJI + case 's': + strcpy(servicesf, optarg); + break; case 't': +#ifdef KANJI if (!setup_term_code (optarg)) { DEBUG(0, ("%s: unknown terminal code name\n", optarg)); usage (pname); exit (1); } +#endif break; -#endif /* KANJI */ default: usage(pname); exit(1); @@ -4285,7 +4498,13 @@ int main(int argc,char *argv[]) DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION)); - get_myname(*myname?NULL:myname,&myip); + if (!lp_load(servicesf,True)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); + return (-1); + } + + load_interfaces(); + get_myname(*myname?NULL:myname,NULL); strupper(myname); if (tar_type) { @@ -4333,9 +4552,9 @@ int main(int argc,char *argv[]) sleep(1); browse_host(True); } - if (!list_servers()) { + if (!list_servers(workgroup)) { sleep(1); - list_servers(); + list_servers(workgroup); } send_logout(); |