diff options
Diffstat (limited to 'source/client')
-rw-r--r-- | source/client/client.c | 1353 | ||||
-rw-r--r-- | source/client/clitar.c | 2573 | ||||
-rwxr-xr-x | source/client/mount.cifs.c | 704 | ||||
-rw-r--r-- | source/client/smbmnt.c | 8 | ||||
-rw-r--r-- | source/client/smbmount.c | 48 | ||||
-rw-r--r-- | source/client/smbspool.c | 11 | ||||
-rw-r--r-- | source/client/tree.c | 12 |
7 files changed, 2237 insertions, 2472 deletions
diff --git a/source/client/client.c b/source/client/client.c index 1da35fcc439..fef258a6b20 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Simo Sorce 2001-2002 Copyright (C) Jelmer Vernooij 2003 + Copyright (C) James J Myers 2003 <myersjj@samba.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,10 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" -#include "../client/client_proto.h" #ifndef REGISTER #define REGISTER 0 #endif @@ -39,15 +37,13 @@ static pstring username; static pstring password; static BOOL use_kerberos; static BOOL got_pass; -static BOOL grepable=False; static char *cmdstr = NULL; static int io_bufsize = 64512; static int name_type = 0x20; -static int max_protocol = PROTOCOL_NT1; -static int process_tok(pstring tok); +static int process_tok(fstring tok); static int cmd_help(void); /* 30 second timeout on most commands */ @@ -102,11 +98,41 @@ static double dir_total; /* some forward declarations */ static struct cli_state *do_connect(const char *server, const char *share); + +/******************************************************************* + Reduce a file name, removing .. elements. +********************************************************************/ +void dos_clean_name(char *s) +{ + char *p=NULL; + + DEBUG(3,("dos_clean_name [%s]\n",s)); + + /* remove any double slashes */ + all_string_sub(s, "\\\\", "\\", 0); + + while ((p = strstr(s,"\\..\\")) != NULL) { + pstring s1; + + *p = 0; + pstrcpy(s1,p+3); + + if ((p=strrchr_m(s,'\\')) != NULL) + *p = 0; + else + *s = 0; + pstrcat(s,s1); + } + + trim_string(s,NULL,"\\.."); + + all_string_sub(s, "\\.\\", "\\", 0); +} + /**************************************************************************** - Write to a local file with CR/LF->LF translation if appropriate. Return the - number taken from the buffer. This may not equal the number written. +write to a local file with CR/LF->LF translation if appropriate. return the +number taken from the buffer. This may not equal the number written. ****************************************************************************/ - static int writefile(int f, char *b, int n) { int i; @@ -131,10 +157,9 @@ static int writefile(int f, char *b, int n) } /**************************************************************************** - Read from a file with LF->CR/LF translation if appropriate. Return the - number read. read approx n bytes. + read from a file with LF->CR/LF translation if appropriate. return the + number read. read approx n bytes. ****************************************************************************/ - static int readfile(char *b, int n, XFILE *f) { int i; @@ -144,7 +169,7 @@ static int readfile(char *b, int n, XFILE *f) return x_fread(b,1,n,f); i = 0; - while (i < (n - 1) && (i < BUFFER_SIZE)) { + while (i < (n - 1) && (i < CLI_BUFFER_SIZE)) { if ((c = x_getc(f)) == EOF) { break; } @@ -159,17 +184,17 @@ static int readfile(char *b, int n, XFILE *f) return(i); } + /**************************************************************************** - Send a message. +send a message ****************************************************************************/ - static void send_message(void) { int total_len = 0; int grp_id; - if (!cli_message_start(cli, desthost, username, &grp_id)) { - d_printf("message start: %s\n", cli_errstr(cli)); + if (!cli_message_start(cli->tree, desthost, username, &grp_id)) { + d_printf("message start: %s\n", cli_errstr(cli->tree)); return; } @@ -190,8 +215,8 @@ static void send_message(void) msg[l] = c; } - if (!cli_message_text(cli, msg, l, grp_id)) { - d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli)); + if (!cli_message_text(cli->tree, msg, l, grp_id)) { + d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli->tree)); return; } @@ -203,22 +228,23 @@ static void send_message(void) else d_printf("sent %d bytes\n",total_len); - if (!cli_message_end(cli, grp_id)) { - d_printf("SMBsendend failed (%s)\n",cli_errstr(cli)); + if (!cli_message_end(cli->tree, grp_id)) { + d_printf("SMBsendend failed (%s)\n",cli_errstr(cli->tree)); return; } } + + /**************************************************************************** - Check the space on a device. +check the space on a device ****************************************************************************/ - static int do_dskattr(void) { int total, bsize, avail; - if (!cli_dskattr(cli, &bsize, &total, &avail)) { - d_printf("Error in dskattr: %s\n",cli_errstr(cli)); + if (NT_STATUS_IS_ERR(cli_dskattr(cli->tree, &bsize, &total, &avail))) { + d_printf("Error in dskattr: %s\n",cli_errstr(cli->tree)); return 1; } @@ -229,9 +255,8 @@ static int do_dskattr(void) } /**************************************************************************** - Show cd/pwd. +show cd/pwd ****************************************************************************/ - static int cmd_pwd(void) { d_printf("Current directory is %s",service); @@ -239,10 +264,10 @@ static int cmd_pwd(void) return 0; } + /**************************************************************************** - Change directory - inner section. +change directory - inner section ****************************************************************************/ - static int do_cd(char *newdir) { char *p = newdir; @@ -267,8 +292,8 @@ static int do_cd(char *newdir) dos_clean_name(cur_dir); if (!strequal(cur_dir,"\\")) { - if (!cli_chkpath(cli, dname)) { - d_printf("cd %s: %s\n", dname, cli_errstr(cli)); + if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, dname))) { + d_printf("cd %s: %s\n", dname, cli_errstr(cli->tree)); pstrcpy(cur_dir,saved_dir); } } @@ -279,12 +304,11 @@ static int do_cd(char *newdir) } /**************************************************************************** - Change directory. +change directory ****************************************************************************/ - static int cmd_cd(void) { - pstring buf; + fstring buf; int rc = 0; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) @@ -295,17 +319,16 @@ static int cmd_cd(void) return rc; } -/******************************************************************* - Decide if a file should be operated on. -********************************************************************/ +/******************************************************************* + decide if a file should be operated on + ********************************************************************/ static BOOL do_this_one(file_info *finfo) { - if (finfo->mode & aDIR) - return(True); + if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) return(True); if (*fileselection && - !mask_match(finfo->name,fileselection,False)) { + !mask_match(cli, finfo->name,fileselection,False)) { DEBUG(3,("mask_match %s failed\n", finfo->name)); return False; } @@ -315,7 +338,7 @@ static BOOL do_this_one(file_info *finfo) return(False); } - if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH)) { + if ((archive_level==1 || archive_level==2) && !(finfo->mode & FILE_ATTRIBUTE_ARCHIVE)) { DEBUG(3,("archive %s failed\n", finfo->name)); return(False); } @@ -323,10 +346,47 @@ static BOOL do_this_one(file_info *finfo) return(True); } -/**************************************************************************** - Display info about a file. -****************************************************************************/ +/******************************************************************* + Return a string representing an attribute for a file. +********************************************************************/ +static const char *attrib_string(uint16 mode) +{ + static fstring attrstr; + int i, len; + const struct { + char c; + uint16 attr; + } attr_strs[] = { + {'V', FILE_ATTRIBUTE_VOLUME}, + {'D', FILE_ATTRIBUTE_DIRECTORY}, + {'A', FILE_ATTRIBUTE_ARCHIVE}, + {'H', FILE_ATTRIBUTE_HIDDEN}, + {'S', FILE_ATTRIBUTE_SYSTEM}, + {'R', FILE_ATTRIBUTE_READONLY}, + {'d', FILE_ATTRIBUTE_DEVICE}, + {'t', FILE_ATTRIBUTE_TEMPORARY}, + {'s', FILE_ATTRIBUTE_SPARSE}, + {'r', FILE_ATTRIBUTE_REPARSE_POINT}, + {'c', FILE_ATTRIBUTE_COMPRESSED}, + {'o', FILE_ATTRIBUTE_OFFLINE}, + {'n', FILE_ATTRIBUTE_NONINDEXED}, + {'e', FILE_ATTRIBUTE_ENCRYPTED} + }; + for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) { + if (mode & attr_strs[i].attr) { + attrstr[len++] = attr_strs[i].c; + } + } + + attrstr[len] = 0; + + return(attrstr); +} + +/**************************************************************************** + display info about a file + ****************************************************************************/ static void display_finfo(file_info *finfo) { if (do_this_one(finfo)) { @@ -340,10 +400,10 @@ static void display_finfo(file_info *finfo) } } -/**************************************************************************** - Accumulate size of a file. -****************************************************************************/ +/**************************************************************************** + accumulate size of a file + ****************************************************************************/ static void do_du(file_info *finfo) { if (do_this_one(finfo)) { @@ -360,8 +420,8 @@ static long do_list_queue_end = 0; static void (*do_list_fn)(file_info *); /**************************************************************************** - Functions for do_list_queue. -****************************************************************************/ +functions for do_list_queue + ****************************************************************************/ /* * The do_list_queue is a NUL-separated list of strings stored in a @@ -374,7 +434,6 @@ static void (*do_list_fn)(file_info *); * Functions check to ensure that do_list_queue is non-NULL before * accessing it. */ - static void reset_do_list_queue(void) { SAFE_FREE(do_list_queue); @@ -403,11 +462,14 @@ static void adjust_do_list_queue(void) * If the starting point of the queue is more than half way through, * move everything toward the beginning. */ - if (do_list_queue && (do_list_queue_start == do_list_queue_end)) { + if (do_list_queue && (do_list_queue_start == do_list_queue_end)) + { DEBUG(4,("do_list_queue is empty\n")); do_list_queue_start = do_list_queue_end = 0; *do_list_queue = '\0'; - } else if (do_list_queue_start > (do_list_queue_size / 2)) { + } + else if (do_list_queue_start > (do_list_queue_size / 2)) + { DEBUG(4,("sliding do_list_queue backward\n")); memmove(do_list_queue, do_list_queue + do_list_queue_start, @@ -415,13 +477,15 @@ static void adjust_do_list_queue(void) do_list_queue_end -= do_list_queue_start; do_list_queue_start = 0; } + } static void add_to_do_list_queue(const char* entry) { char *dlq; long new_end = do_list_queue_end + ((long)strlen(entry)) + 1; - while (new_end > do_list_queue_size) { + while (new_end > do_list_queue_size) + { do_list_queue_size *= 2; DEBUG(4,("enlarging do_list_queue to %d\n", (int)do_list_queue_size)); @@ -430,15 +494,18 @@ static void add_to_do_list_queue(const char* entry) d_printf("failure enlarging do_list_queue to %d bytes\n", (int)do_list_queue_size); reset_do_list_queue(); - } else { + } + else + { do_list_queue = dlq; memset(do_list_queue + do_list_queue_size / 2, 0, do_list_queue_size / 2); } } - if (do_list_queue) { - safe_strcpy_base(do_list_queue + do_list_queue_end, - entry, do_list_queue, do_list_queue_size); + if (do_list_queue) + { + safe_strcpy(do_list_queue + do_list_queue_end, entry, + do_list_queue_size - do_list_queue_end - 1); do_list_queue_end = new_end; DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n", entry, (int)do_list_queue_start, (int)do_list_queue_end)); @@ -452,7 +519,8 @@ static char *do_list_queue_head(void) static void remove_do_list_queue_head(void) { - if (do_list_queue_end > do_list_queue_start) { + if (do_list_queue_end > do_list_queue_start) + { do_list_queue_start += strlen(do_list_queue_head()) + 1; adjust_do_list_queue(); DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n", @@ -466,12 +534,11 @@ static int do_list_queue_empty(void) } /**************************************************************************** - A helper for do_list. -****************************************************************************/ - +a helper for do_list + ****************************************************************************/ static void do_list_helper(file_info *f, const char *mask, void *state) { - if (f->mode & aDIR) { + if (f->mode & FILE_ATTRIBUTE_DIRECTORY) { if (do_list_dirs && do_this_one(f)) { do_list_fn(f); } @@ -481,15 +548,9 @@ static void do_list_helper(file_info *f, const char *mask, void *state) pstring mask2; char *p; - if (!f->name[0]) { - d_printf("Empty dir name returned. Possible server misconfiguration.\n"); - return; - } - pstrcpy(mask2, mask); p = strrchr_m(mask2,'\\'); - if (!p) - return; + if (!p) return; p[1] = 0; pstrcat(mask2, f->name); pstrcat(mask2,"\\*"); @@ -503,15 +564,16 @@ static void do_list_helper(file_info *f, const char *mask, void *state) } } -/**************************************************************************** - A wrapper around cli_list that adds recursion. -****************************************************************************/ +/**************************************************************************** +a wrapper around cli_list that adds recursion + ****************************************************************************/ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs) { static int in_do_list = 0; - if (in_do_list && rec) { + if (in_do_list && rec) + { fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n"); exit(1); } @@ -522,11 +584,13 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, do_list_dirs = dirs; do_list_fn = fn; - if (rec) { + if (rec) + { init_do_list_queue(); add_to_do_list_queue(mask); - while (! do_list_queue_empty()) { + while (! do_list_queue_empty()) + { /* * Need to copy head so that it doesn't become * invalid inside the call to cli_list. This @@ -536,27 +600,33 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, */ pstring head; pstrcpy(head, do_list_queue_head()); - cli_list(cli, head, attribute, do_list_helper, NULL); + cli_list(cli->tree, head, attribute, do_list_helper, NULL); remove_do_list_queue_head(); - if ((! do_list_queue_empty()) && (fn == display_finfo)) { + if ((! do_list_queue_empty()) && (fn == display_finfo)) + { char* next_file = do_list_queue_head(); char* save_ch = 0; if ((strlen(next_file) >= 2) && (next_file[strlen(next_file) - 1] == '*') && - (next_file[strlen(next_file) - 2] == '\\')) { + (next_file[strlen(next_file) - 2] == '\\')) + { save_ch = next_file + strlen(next_file) - 2; *save_ch = '\0'; } d_printf("\n%s\n",next_file); - if (save_ch) { + if (save_ch) + { *save_ch = '\\'; } } } - } else { - if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1) { - d_printf("%s listing %s\n", cli_errstr(cli), mask); + } + else + { + if (cli_list(cli->tree, mask, attribute, do_list_helper, NULL) == -1) + { + d_printf("%s listing %s\n", cli_errstr(cli->tree), mask); } } @@ -565,25 +635,20 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, } /**************************************************************************** - Get a directory listing. -****************************************************************************/ - + get a directory listing + ****************************************************************************/ static int cmd_dir(void) { - uint16 attribute = aDIR | aSYSTEM | aHIDDEN; + uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; pstring mask; - pstring buf; + fstring buf; char *p=buf; int rc; dir_total = 0; - if (strcmp(cur_dir, "\\") != 0) { - pstrcpy(mask,cur_dir); - if(mask[strlen(mask)-1]!='\\') - pstrcat(mask,"\\"); - } else { - *mask = '\0'; - } + pstrcpy(mask,cur_dir); + if(mask[strlen(mask)-1]!='\\') + pstrcat(mask,"\\"); if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { dos_format(p); @@ -591,7 +656,8 @@ static int cmd_dir(void) pstrcpy(mask,p); else pstrcat(mask,p); - } else { + } + else { pstrcat(mask,"*"); } @@ -604,15 +670,15 @@ static int cmd_dir(void) return rc; } -/**************************************************************************** - Get a directory listing. -****************************************************************************/ +/**************************************************************************** + get a directory listing + ****************************************************************************/ static int cmd_du(void) { - uint16 attribute = aDIR | aSYSTEM | aHIDDEN; + uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; pstring mask; - pstring buf; + fstring buf; char *p=buf; int rc; @@ -640,11 +706,11 @@ static int cmd_du(void) return rc; } -/**************************************************************************** - Get a file from rname to lname -****************************************************************************/ -static int do_get(char *rname, char *lname, BOOL reget) +/**************************************************************************** + get a file from rname to lname + ****************************************************************************/ +static int do_get(char *rname, const char *lname, BOOL reget) { int handle = 0, fnum; BOOL newhandle = False; @@ -660,13 +726,13 @@ static int do_get(char *rname, char *lname, BOOL reget) GetTimeOfDay(&tp_start); if (lowercase) { - strlower_m(lname); + strlower(lname); } - fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE); + fnum = cli_open(cli->tree, rname, O_RDONLY, DENY_NONE); if (fnum == -1) { - d_printf("%s opening remote file %s\n",cli_errstr(cli),rname); + d_printf("%s opening remote file %s\n",cli_errstr(cli->tree),rname); return 1; } @@ -693,11 +759,11 @@ static int do_get(char *rname, char *lname, BOOL reget) } - if (!cli_qfileinfo(cli, fnum, - &attr, &size, NULL, NULL, NULL, NULL, NULL) && - !cli_getattrE(cli, fnum, - &attr, &size, NULL, NULL, NULL)) { - d_printf("getattrib: %s\n",cli_errstr(cli)); + if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, + &attr, &size, NULL, NULL, NULL, NULL, NULL)) && + NT_STATUS_IS_ERR(cli_getattrE(cli->tree, fnum, + &attr, &size, NULL, NULL, NULL))) { + d_printf("getattrib: %s\n",cli_errstr(cli->tree)); return 1; } @@ -706,15 +772,14 @@ static int do_get(char *rname, char *lname, BOOL reget) if(!(data = (char *)malloc(read_size))) { d_printf("malloc fail for size %d\n", read_size); - cli_close(cli, fnum); + cli_close(cli->tree, fnum); return 1; } while (1) { - int n = cli_read(cli, fnum, data, nread + start, read_size); + int n = cli_read(cli->tree, fnum, data, nread + start, read_size); - if (n <= 0) - break; + if (n <= 0) break; if (writefile(handle,data, n) != n) { d_printf("Error writing local file\n"); @@ -734,8 +799,8 @@ static int do_get(char *rname, char *lname, BOOL reget) SAFE_FREE(data); - if (!cli_close(cli, fnum)) { - d_printf("Error %s closing remote file\n",cli_errstr(cli)); + if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) { + d_printf("Error %s closing remote file\n",cli_errstr(cli->tree)); rc = 1; } @@ -743,8 +808,8 @@ static int do_get(char *rname, char *lname, BOOL reget) close(handle); } - if (archive_level >= 2 && (attr & aARCH)) { - cli_setatr(cli, rname, attr & ~(uint16)aARCH, 0); + if (archive_level >= 2 && (attr & FILE_ATTRIBUTE_ARCHIVE)) { + cli_setatr(cli->tree, rname, attr & ~(uint16)FILE_ATTRIBUTE_ARCHIVE, 0); } { @@ -766,10 +831,10 @@ static int do_get(char *rname, char *lname, BOOL reget) return rc; } -/**************************************************************************** - Get a file. -****************************************************************************/ +/**************************************************************************** + get a file + ****************************************************************************/ static int cmd_get(void) { pstring lname; @@ -793,10 +858,10 @@ static int cmd_get(void) return do_get(rname, lname, False); } -/**************************************************************************** - Do an mget operation on one file. -****************************************************************************/ +/**************************************************************************** + do a mget operation on one file + ****************************************************************************/ static void do_mget(file_info *finfo) { pstring rname; @@ -812,17 +877,16 @@ static void do_mget(file_info *finfo) return; } - if (finfo->mode & aDIR) + if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) slprintf(quest,sizeof(pstring)-1, "Get directory %s? ",finfo->name); else slprintf(quest,sizeof(pstring)-1, "Get file %s? ",finfo->name); - if (prompt && !yesno(quest)) - return; + if (prompt && !yesno(quest)) return; - if (!(finfo->mode & aDIR)) { + if (!(finfo->mode & FILE_ATTRIBUTE_DIRECTORY)) { pstrcpy(rname,cur_dir); pstrcat(rname,finfo->name); do_get(rname, finfo->name, False); @@ -837,7 +901,7 @@ static void do_mget(file_info *finfo) unix_format(finfo->name); if (lowercase) - strlower_m(finfo->name); + strlower(finfo->name); if (!directory_exist(finfo->name,NULL) && mkdir(finfo->name,0777) != 0) { @@ -855,24 +919,24 @@ static void do_mget(file_info *finfo) pstrcpy(mget_mask,cur_dir); pstrcat(mget_mask,"*"); - do_list(mget_mask, aSYSTEM | aHIDDEN | aDIR,do_mget,False, True); + do_list(mget_mask, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY,do_mget,False, True); chdir(".."); pstrcpy(cur_dir,saved_curdir); } + /**************************************************************************** - View the file using the pager. +view the file using the pager ****************************************************************************/ - static int cmd_more(void) { - pstring rname,lname,pager_cmd; + fstring rname,lname,pager_cmd; char *pager; int fd; int rc = 0; - pstrcpy(rname,cur_dir); - pstrcat(rname,"\\"); + fstrcpy(rname,cur_dir); + fstrcat(rname,"\\"); slprintf(lname,sizeof(lname)-1, "%s/smbmore.XXXXXX",tmpdir()); fd = smb_mkstemp(lname); @@ -901,21 +965,22 @@ static int cmd_more(void) return rc; } + + /**************************************************************************** - Do a mget command. +do a mget command ****************************************************************************/ - static int cmd_mget(void) { - uint16 attribute = aSYSTEM | aHIDDEN; + uint16 attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; pstring mget_mask; - pstring buf; + fstring buf; char *p=buf; *mget_mask = 0; if (recurse) - attribute |= aDIR; + attribute |= FILE_ATTRIBUTE_DIRECTORY; abort_mget = False; @@ -942,31 +1007,32 @@ static int cmd_mget(void) return 0; } + /**************************************************************************** - Make a directory of name "name". +make a directory of name "name" ****************************************************************************/ - -static BOOL do_mkdir(char *name) +static NTSTATUS do_mkdir(char *name) { - if (!cli_mkdir(cli, name)) { + NTSTATUS status; + + if (NT_STATUS_IS_ERR(status = cli_mkdir(cli->tree, name))) { d_printf("%s making remote directory %s\n", - cli_errstr(cli),name); - return(False); + cli_errstr(cli->tree),name); + return status; } - return(True); + return status; } /**************************************************************************** - Show 8.3 name of a file. +show 8.3 name of a file ****************************************************************************/ - static BOOL do_altname(char *name) { - pstring altname; - if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli, name, altname))) { + const char *altname; + if (!NT_STATUS_IS_OK(cli_qpathinfo_alt_name(cli->tree, name, &altname))) { d_printf("%s getting alt name for %s\n", - cli_errstr(cli),name); + cli_errstr(cli->tree),name); return(False); } d_printf("%s\n", altname); @@ -974,10 +1040,10 @@ static BOOL do_altname(char *name) return(True); } + /**************************************************************************** Exit client. ****************************************************************************/ - static int cmd_quit(void) { cli_shutdown(cli); @@ -986,14 +1052,14 @@ static int cmd_quit(void) return 0; } -/**************************************************************************** - Make a directory. -****************************************************************************/ +/**************************************************************************** + make a directory + ****************************************************************************/ static int cmd_mkdir(void) { pstring mask; - pstring buf; + fstring buf; char *p=buf; pstrcpy(mask,cur_dir); @@ -1011,11 +1077,11 @@ static int cmd_mkdir(void) *ddir2 = 0; pstrcpy(ddir,mask); - trim_char(ddir,'.','\0'); + trim_string(ddir,".",NULL); p = strtok(ddir,"/\\"); while (p) { pstrcat(ddir2,p); - if (!cli_chkpath(cli, ddir2)) { + if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, ddir2))) { do_mkdir(ddir2); } pstrcat(ddir2,"\\"); @@ -1028,14 +1094,14 @@ static int cmd_mkdir(void) return 0; } -/**************************************************************************** - Show alt name. -****************************************************************************/ +/**************************************************************************** + show alt name + ****************************************************************************/ static int cmd_altname(void) { pstring name; - pstring buf; + fstring buf; char *p=buf; pstrcpy(name,cur_dir); @@ -1051,10 +1117,10 @@ static int cmd_altname(void) return 0; } -/**************************************************************************** - Put a single file. -****************************************************************************/ +/**************************************************************************** + put a single file + ****************************************************************************/ static int do_put(char *rname, char *lname, BOOL reput) { int fnum; @@ -1069,20 +1135,21 @@ static int do_put(char *rname, char *lname, BOOL reput) GetTimeOfDay(&tp_start); if (reput) { - fnum = cli_open(cli, rname, O_RDWR|O_CREAT, DENY_NONE); + fnum = cli_open(cli->tree, rname, O_RDWR|O_CREAT, DENY_NONE); if (fnum >= 0) { - if (!cli_qfileinfo(cli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) && - !cli_getattrE(cli, fnum, NULL, &start, NULL, NULL, NULL)) { - d_printf("getattrib: %s\n",cli_errstr(cli)); + if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL)) && + NT_STATUS_IS_ERR(cli_getattrE(cli->tree, fnum, NULL, &start, NULL, NULL, NULL))) { + d_printf("getattrib: %s\n",cli_errstr(cli->tree)); return 1; } } } else { - fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE); + fnum = cli_open(cli->tree, rname, O_RDWR|O_CREAT|O_TRUNC, + DENY_NONE); } if (fnum == -1) { - d_printf("%s opening remote file %s\n",cli_errstr(cli),rname); + d_printf("%s opening remote file %s\n",cli_errstr(cli->tree),rname); return 1; } @@ -1108,6 +1175,7 @@ static int do_put(char *rname, char *lname, BOOL reput) d_printf("Error opening local file %s\n",lname); return 1; } + DEBUG(1,("putting file %s as %s ",lname, rname)); @@ -1130,10 +1198,10 @@ static int do_put(char *rname, char *lname, BOOL reput) break; } - ret = cli_write(cli, fnum, 0, buf, nread + start, n); + ret = cli_write(cli->tree, fnum, 0, buf, nread + start, n); if (n != ret) { - d_printf("Error writing file: %s\n", cli_errstr(cli)); + d_printf("Error writing file: %s\n", cli_errstr(cli->tree)); rc = 1; break; } @@ -1141,8 +1209,8 @@ static int do_put(char *rname, char *lname, BOOL reput) nread += n; } - if (!cli_close(cli, fnum)) { - d_printf("%s closing remote file %s\n",cli_errstr(cli),rname); + if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) { + d_printf("%s closing remote file %s\n",cli_errstr(cli->tree),rname); x_fclose(f); SAFE_FREE(buf); return 1; @@ -1179,15 +1247,16 @@ static int do_put(char *rname, char *lname, BOOL reput) return rc; } -/**************************************************************************** - Put a file. -****************************************************************************/ + +/**************************************************************************** + put a file + ****************************************************************************/ static int cmd_put(void) { pstring lname; pstring rname; - pstring buf; + fstring buf; char *p=buf; pstrcpy(rname,cur_dir); @@ -1221,7 +1290,7 @@ static int cmd_put(void) } /************************************* - File list structure. + File list structure *************************************/ static struct file_list { @@ -1231,14 +1300,15 @@ static struct file_list { } *file_list; /**************************************************************************** - Free a file_list structure. + Free a file_list structure ****************************************************************************/ static void free_file_list (struct file_list * list) { struct file_list *tmp; - while (list) { + while (list) + { tmp = list; DLIST_REMOVE(list, list); SAFE_FREE(tmp->file_path); @@ -1247,10 +1317,9 @@ static void free_file_list (struct file_list * list) } /**************************************************************************** - Seek in a directory/file list until you get something that doesn't start with - the specified name. -****************************************************************************/ - + seek in a directory/file list until you get something that doesn't start with + the specified name + ****************************************************************************/ static BOOL seek_list(struct file_list *list, char *name) { while (list) { @@ -1265,9 +1334,8 @@ static BOOL seek_list(struct file_list *list, char *name) } /**************************************************************************** - Set the file selection mask. -****************************************************************************/ - + set the file selection mask + ****************************************************************************/ static int cmd_select(void) { pstrcpy(fileselection,""); @@ -1280,7 +1348,6 @@ static int cmd_select(void) Recursive file matching function act as find match must be always set to True when calling this function ****************************************************************************/ - static int file_find(struct file_list **list, const char *directory, const char *expression, BOOL match) { @@ -1293,14 +1360,11 @@ static int file_find(struct file_list **list, const char *directory, const char *dname; dir = opendir(directory); - if (!dir) - return -1; + if (!dir) return -1; while ((dname = readdirname(dir))) { - if (!strcmp("..", dname)) - continue; - if (!strcmp(".", dname)) - continue; + if (!strcmp("..", dname)) continue; + if (!strcmp(".", dname)) continue; if (asprintf(&path, "%s/%s", directory, dname) <= 0) { continue; @@ -1344,12 +1408,11 @@ static int file_find(struct file_list **list, const char *directory, } /**************************************************************************** - mput some files. -****************************************************************************/ - + mput some files + ****************************************************************************/ static int cmd_mput(void) { - pstring buf; + fstring buf; char *p=buf; while (next_token_nr(NULL,p,NULL,sizeof(buf))) { @@ -1392,8 +1455,8 @@ static int cmd_mput(void) SAFE_FREE(rname); if(asprintf(&rname, "%s%s", cur_dir, lname) < 0) break; dos_format(rname); - if (!cli_chkpath(cli, rname) && - !do_mkdir(rname)) { + if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, rname)) && + NT_STATUS_IS_ERR(do_mkdir(rname))) { DEBUG (0, ("Unable to make dir, skipping...")); /* Skip the directory */ lname[strlen(lname)-1] = '/'; @@ -1426,28 +1489,23 @@ static int cmd_mput(void) return 0; } -/**************************************************************************** - Cancel a print job. -****************************************************************************/ +/**************************************************************************** + cancel a print job + ****************************************************************************/ static int do_cancel(int job) { - if (cli_printjob_del(cli, job)) { - d_printf("Job %d cancelled\n",job); - return 0; - } else { - d_printf("Error cancelling job %d : %s\n",job,cli_errstr(cli)); - return 1; - } + d_printf("REWRITE: print job cancel not implemented\n"); + return 1; } -/**************************************************************************** - Cancel a print job. -****************************************************************************/ +/**************************************************************************** + cancel a print job + ****************************************************************************/ static int cmd_cancel(void) { - pstring buf; + fstring buf; int job; if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { @@ -1462,10 +1520,10 @@ static int cmd_cancel(void) return 0; } -/**************************************************************************** - Print a file. -****************************************************************************/ +/**************************************************************************** + print a file + ****************************************************************************/ static int cmd_print(void) { pstring lname; @@ -1480,40 +1538,30 @@ static int cmd_print(void) pstrcpy(rname,lname); p = strrchr_m(rname,'/'); if (p) { - slprintf(rname, sizeof(rname)-1, "%s-%d", p+1, (int)sys_getpid()); + slprintf(rname, sizeof(rname)-1, "%s-%d", p+1, (int)getpid()); } if (strequal(lname,"-")) { - slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)sys_getpid()); + slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)getpid()); } return do_put(rname, lname, False); } -/**************************************************************************** - Show a print queue entry. -****************************************************************************/ - -static void queue_fn(struct print_job_info *p) -{ - d_printf("%-6d %-9d %s\n", (int)p->id, (int)p->size, p->name); -} /**************************************************************************** - Show a print queue. + show a print queue ****************************************************************************/ - static int cmd_queue(void) { - cli_print_queue(cli, queue_fn); + d_printf("REWRITE: print job queue not implemented\n"); return 0; } /**************************************************************************** - Delete some files. +delete some files ****************************************************************************/ - static void do_del(file_info *finfo) { pstring mask; @@ -1521,26 +1569,25 @@ static void do_del(file_info *finfo) pstrcpy(mask,cur_dir); pstrcat(mask,finfo->name); - if (finfo->mode & aDIR) + if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) return; - if (!cli_unlink(cli, mask)) { - d_printf("%s deleting remote file %s\n",cli_errstr(cli),mask); + if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, mask))) { + d_printf("%s deleting remote file %s\n",cli_errstr(cli->tree),mask); } } /**************************************************************************** - Delete some files. +delete some files ****************************************************************************/ - static int cmd_del(void) { pstring mask; - pstring buf; - uint16 attribute = aSYSTEM | aHIDDEN; + fstring buf; + uint16 attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; if (recurse) - attribute |= aDIR; + attribute |= FILE_ATTRIBUTE_DIRECTORY; pstrcpy(mask,cur_dir); @@ -1555,13 +1602,197 @@ static int cmd_del(void) return 0; } + +/**************************************************************************** +delete a whole directory tree +****************************************************************************/ +static int cmd_deltree(void) +{ + pstring dname; + fstring buf; + int ret; + + pstrcpy(dname,cur_dir); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("deltree <dirname>\n"); + return 1; + } + pstrcat(dname,buf); + + ret = cli_deltree(cli->tree, dname); + + if (ret == -1) { + printf("Failed to delete tree %s - %s\n", dname, cli_errstr(cli->tree)); + return -1; + } + + printf("Deleted %d files in %s\n", ret, dname); + + return 0; +} + + +/**************************************************************************** +show as much information as possible about a file +****************************************************************************/ +static int cmd_allinfo(void) +{ + pstring fname; + fstring buf; + int ret = 0; + TALLOC_CTX *mem_ctx; + union smb_fileinfo finfo; + NTSTATUS status; + + pstrcpy(fname,cur_dir); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("allinfo <filename>\n"); + return 1; + } + pstrcat(fname,buf); + + mem_ctx = talloc_init(fname); + + /* first a ALL_INFO QPATHINFO */ + finfo.generic.level = RAW_FILEINFO_ALL_INFO; + finfo.generic.in.fname = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (!NT_STATUS_IS_OK(status)) { + d_printf("%s - %s\n", fname, nt_errstr(status)); + ret = 1; + goto done; + } + + d_printf("\tcreate_time: %s\n", nt_time_string(mem_ctx, &finfo.all_info.out.create_time)); + d_printf("\taccess_time: %s\n", nt_time_string(mem_ctx, &finfo.all_info.out.access_time)); + d_printf("\twrite_time: %s\n", nt_time_string(mem_ctx, &finfo.all_info.out.write_time)); + d_printf("\tchange_time: %s\n", nt_time_string(mem_ctx, &finfo.all_info.out.change_time)); + d_printf("\tattrib: 0x%x\n", finfo.all_info.out.attrib); + d_printf("\talloc_size: %lu\n", (unsigned long)finfo.all_info.out.alloc_size); + d_printf("\tsize: %lu\n", (unsigned long)finfo.all_info.out.size); + d_printf("\tnlink: %u\n", finfo.all_info.out.nlink); + d_printf("\tdelete_pending: %u\n", finfo.all_info.out.delete_pending); + d_printf("\tdirectory: %u\n", finfo.all_info.out.directory); + d_printf("\tea_size: %u\n", finfo.all_info.out.ea_size); + d_printf("\tfname: '%s'\n", finfo.all_info.out.fname.s); + + /* 8.3 name if any */ + finfo.generic.level = RAW_FILEINFO_ALT_NAME_INFO; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (NT_STATUS_IS_OK(status)) { + d_printf("\talt_name: %s\n", finfo.alt_name_info.out.fname.s); + } + + /* file_id if available */ + finfo.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (NT_STATUS_IS_OK(status)) { + d_printf("\tfile_id %.0f\n", + (double)finfo.internal_information.out.file_id); + } + + /* the EAs, if any */ + finfo.generic.level = RAW_FILEINFO_ALL_EAS; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (NT_STATUS_IS_OK(status)) { + int i; + for (i=0;i<finfo.all_eas.out.num_eas;i++) { + d_printf("\tEA[%d] flags=%d %s=%*.*s\n", i, + finfo.all_eas.out.eas[i].flags, + finfo.all_eas.out.eas[i].name.s, + finfo.all_eas.out.eas[i].value.length, + finfo.all_eas.out.eas[i].value.length, + finfo.all_eas.out.eas[i].value.data); + } + } + + /* streams, if available */ + finfo.generic.level = RAW_FILEINFO_STREAM_INFO; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (NT_STATUS_IS_OK(status)) { + int i; + for (i=0;i<finfo.stream_info.out.num_streams;i++) { + d_printf("\tstream %d:\n", i); + d_printf("\t\tsize %ld\n", + (long)finfo.stream_info.out.streams[i].size); + d_printf("\t\talloc size %ld\n", + (long)finfo.stream_info.out.streams[i].alloc_size); + d_printf("\t\tname %s\n", finfo.stream_info.out.streams[i].stream_name.s); + } + } + + /* dev/inode if available */ + finfo.generic.level = RAW_FILEINFO_COMPRESSION_INFORMATION; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (NT_STATUS_IS_OK(status)) { + d_printf("\tcompressed size %ld\n", (long)finfo.compression_info.out.compressed_size); + d_printf("\tformat %ld\n", (long)finfo.compression_info.out.format); + d_printf("\tunit_shift %ld\n", (long)finfo.compression_info.out.unit_shift); + d_printf("\tchunk_shift %ld\n", (long)finfo.compression_info.out.chunk_shift); + d_printf("\tcluster_shift %ld\n", (long)finfo.compression_info.out.cluster_shift); + } + + talloc_destroy(mem_ctx); + +done: + return ret; +} + + /**************************************************************************** +show any ACL on a file ****************************************************************************/ +static int cmd_acl(void) +{ + pstring fname; + fstring buf; + int ret = 0; + TALLOC_CTX *mem_ctx; + struct smb_query_secdesc query; + NTSTATUS status; + int fnum; + pstrcpy(fname,cur_dir); + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { + d_printf("acl <filename>\n"); + return 1; + } + pstrcat(fname,buf); + + fnum = cli_open(cli->tree, fname, O_RDONLY, DENY_NONE); + if (fnum == -1) { + d_printf("%s - %s\n", fname, cli_errstr(cli->tree)); + return -1; + } + + mem_ctx = talloc_init(fname); + + query.in.fnum = fnum; + query.in.secinfo_flags = 0x7; + + status = smb_raw_query_secdesc(cli->tree, mem_ctx, &query); + if (!NT_STATUS_IS_OK(status)) { + d_printf("%s - %s\n", fname, nt_errstr(status)); + ret = 1; + goto done; + } + + talloc_destroy(mem_ctx); + +done: + return ret; +} + + +/**************************************************************************** +****************************************************************************/ static int cmd_open(void) { pstring mask; - pstring buf; + fstring buf; pstrcpy(mask,cur_dir); @@ -1571,20 +1802,19 @@ static int cmd_open(void) } pstrcat(mask,buf); - cli_open(cli, mask, O_RDWR, DENY_ALL); + cli_open(cli->tree, mask, O_RDWR, DENY_ALL); return 0; } /**************************************************************************** - Remove a directory. +remove a directory ****************************************************************************/ - static int cmd_rmdir(void) { pstring mask; - pstring buf; + fstring buf; pstrcpy(mask,cur_dir); @@ -1594,9 +1824,9 @@ static int cmd_rmdir(void) } pstrcat(mask,buf); - if (!cli_rmdir(cli, mask)) { + if (NT_STATUS_IS_ERR(cli_rmdir(cli->tree, mask))) { d_printf("%s removing remote directory file %s\n", - cli_errstr(cli),mask); + cli_errstr(cli->tree),mask); } return 0; @@ -1605,13 +1835,12 @@ static int cmd_rmdir(void) /**************************************************************************** UNIX hardlink. ****************************************************************************/ - static int cmd_link(void) { pstring src,dest; - pstring buf,buf2; + fstring buf,buf2; - if (!SERVER_HAS_UNIX_CIFS(cli)) { + if (!(cli->transport->negotiate.capabilities & CAP_UNIX)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); return 1; } @@ -1619,8 +1848,8 @@ static int cmd_link(void) pstrcpy(src,cur_dir); pstrcpy(dest,cur_dir); - if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || - !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { + if (!next_token(NULL,buf,NULL,sizeof(buf)) || + !next_token(NULL,buf2,NULL, sizeof(buf2))) { d_printf("link <src> <dest>\n"); return 1; } @@ -1628,8 +1857,8 @@ static int cmd_link(void) pstrcat(src,buf); pstrcat(dest,buf2); - if (!cli_unix_hardlink(cli, src, dest)) { - d_printf("%s linking files (%s -> %s)\n", cli_errstr(cli), src, dest); + if (NT_STATUS_IS_ERR(cli_unix_hardlink(cli->tree, src, dest))) { + d_printf("%s linking files (%s -> %s)\n", cli_errstr(cli->tree), src, dest); return 1; } @@ -1643,9 +1872,9 @@ static int cmd_link(void) static int cmd_symlink(void) { pstring src,dest; - pstring buf,buf2; + fstring buf,buf2; - if (!SERVER_HAS_UNIX_CIFS(cli)) { + if (!(cli->transport->negotiate.capabilities & CAP_UNIX)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); return 1; } @@ -1653,8 +1882,8 @@ static int cmd_symlink(void) pstrcpy(src,cur_dir); pstrcpy(dest,cur_dir); - if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || - !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { + if (!next_token(NULL,buf,NULL,sizeof(buf)) || + !next_token(NULL,buf2,NULL, sizeof(buf2))) { d_printf("symlink <src> <dest>\n"); return 1; } @@ -1662,9 +1891,9 @@ static int cmd_symlink(void) pstrcat(src,buf); pstrcat(dest,buf2); - if (!cli_unix_symlink(cli, src, dest)) { + if (NT_STATUS_IS_ERR(cli_unix_symlink(cli->tree, src, dest))) { d_printf("%s symlinking files (%s -> %s)\n", - cli_errstr(cli), src, dest); + cli_errstr(cli->tree), src, dest); return 1; } @@ -1679,17 +1908,17 @@ static int cmd_chmod(void) { pstring src; mode_t mode; - pstring buf, buf2; + fstring buf, buf2; - if (!SERVER_HAS_UNIX_CIFS(cli)) { + if (!(cli->transport->negotiate.capabilities & CAP_UNIX)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); return 1; } pstrcpy(src,cur_dir); - if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || - !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { + if (!next_token(NULL,buf,NULL,sizeof(buf)) || + !next_token(NULL,buf2,NULL, sizeof(buf2))) { d_printf("chmod mode file\n"); return 1; } @@ -1697,9 +1926,9 @@ static int cmd_chmod(void) mode = (mode_t)strtol(buf, NULL, 8); pstrcat(src,buf2); - if (!cli_unix_chmod(cli, src, mode)) { + if (NT_STATUS_IS_ERR(cli_unix_chmod(cli->tree, src, mode))) { d_printf("%s chmod file %s 0%o\n", - cli_errstr(cli), src, (unsigned int)mode); + cli_errstr(cli->tree), src, (unsigned int)mode); return 1; } @@ -1715,18 +1944,18 @@ static int cmd_chown(void) pstring src; uid_t uid; gid_t gid; - pstring buf, buf2, buf3; + fstring buf, buf2, buf3; - if (!SERVER_HAS_UNIX_CIFS(cli)) { + if (!(cli->transport->negotiate.capabilities & CAP_UNIX)) { d_printf("Server doesn't support UNIX CIFS calls.\n"); return 1; } pstrcpy(src,cur_dir); - if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || - !next_token_nr(NULL,buf2,NULL, sizeof(buf2)) || - !next_token_nr(NULL,buf3,NULL, sizeof(buf3))) { + if (!next_token(NULL,buf,NULL,sizeof(buf)) || + !next_token(NULL,buf2,NULL, sizeof(buf2)) || + !next_token(NULL,buf3,NULL, sizeof(buf3))) { d_printf("chown uid gid file\n"); return 1; } @@ -1735,9 +1964,9 @@ static int cmd_chown(void) gid = (gid_t)atoi(buf2); pstrcat(src,buf3); - if (!cli_unix_chown(cli, src, uid, gid)) { + if (NT_STATUS_IS_ERR(cli_unix_chown(cli->tree, src, uid, gid))) { d_printf("%s chown file %s uid=%d, gid=%d\n", - cli_errstr(cli), src, (int)uid, (int)gid); + cli_errstr(cli->tree), src, (int)uid, (int)gid); return 1; } @@ -1745,13 +1974,12 @@ static int cmd_chown(void) } /**************************************************************************** - Rename some file. +rename some files ****************************************************************************/ - static int cmd_rename(void) { pstring src,dest; - pstring buf,buf2; + fstring buf,buf2; pstrcpy(src,cur_dir); pstrcpy(dest,cur_dir); @@ -1765,47 +1993,18 @@ static int cmd_rename(void) pstrcat(src,buf); pstrcat(dest,buf2); - if (!cli_rename(cli, src, dest)) { - d_printf("%s renaming files\n",cli_errstr(cli)); + if (NT_STATUS_IS_ERR(cli_rename(cli->tree, src, dest))) { + d_printf("%s renaming files\n",cli_errstr(cli->tree)); return 1; } return 0; } -/**************************************************************************** - Hard link files using the NT call. -****************************************************************************/ - -static int cmd_hardlink(void) -{ - pstring src,dest; - pstring buf,buf2; - - pstrcpy(src,cur_dir); - pstrcpy(dest,cur_dir); - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf)) || - !next_token_nr(NULL,buf2,NULL, sizeof(buf2))) { - d_printf("hardlink <src> <dest>\n"); - return 1; - } - - pstrcat(src,buf); - pstrcat(dest,buf2); - - if (!cli_nt_hardlink(cli, src, dest)) { - d_printf("%s doing an NT hard link of files\n",cli_errstr(cli)); - return 1; - } - - return 0; -} /**************************************************************************** - Toggle the prompt flag. +toggle the prompt flag ****************************************************************************/ - static int cmd_prompt(void) { prompt = !prompt; @@ -1814,13 +2013,13 @@ static int cmd_prompt(void) return 1; } + /**************************************************************************** - Set the newer than time. +set the newer than time ****************************************************************************/ - static int cmd_newer(void) { - pstring buf; + fstring buf; BOOL ok; SMB_STRUCT_STAT sbuf; @@ -1842,12 +2041,11 @@ static int cmd_newer(void) } /**************************************************************************** - Set the archive level. +set the archive level ****************************************************************************/ - static int cmd_archive(void) { - pstring buf; + fstring buf; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { archive_level = atoi(buf); @@ -1858,9 +2056,8 @@ static int cmd_archive(void) } /**************************************************************************** - Toggle the lowercaseflag. +toggle the lowercaseflag ****************************************************************************/ - static int cmd_lowercase(void) { lowercase = !lowercase; @@ -1869,10 +2066,12 @@ static int cmd_lowercase(void) return 0; } + + + /**************************************************************************** - Toggle the recurse flag. +toggle the recurse flag ****************************************************************************/ - static int cmd_recurse(void) { recurse = !recurse; @@ -1882,9 +2081,8 @@ static int cmd_recurse(void) } /**************************************************************************** - Toggle the translate flag. +toggle the translate flag ****************************************************************************/ - static int cmd_translate(void) { translation = !translation; @@ -1894,10 +2092,10 @@ static int cmd_translate(void) return 0; } + /**************************************************************************** - Do a printmode command. +do a printmode command ****************************************************************************/ - static int cmd_printmode(void) { fstring buf; @@ -1914,7 +2112,8 @@ static int cmd_printmode(void) } } - switch(printmode) { + switch(printmode) + { case 0: fstrcpy(mode,"text"); break; @@ -1924,7 +2123,7 @@ static int cmd_printmode(void) default: slprintf(mode,sizeof(mode)-1,"%d",printmode); break; - } + } DEBUG(2,("the printmode is now %s\n",mode)); @@ -1932,12 +2131,11 @@ static int cmd_printmode(void) } /**************************************************************************** - Do the lcd command. + do the lcd command ****************************************************************************/ - static int cmd_lcd(void) { - pstring buf; + fstring buf; pstring d; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) @@ -1948,9 +2146,8 @@ static int cmd_lcd(void) } /**************************************************************************** - Get a file restarting at end of local file. + get a file restarting at end of local file ****************************************************************************/ - static int cmd_reget(void) { pstring local_name; @@ -1975,14 +2172,13 @@ static int cmd_reget(void) } /**************************************************************************** - Put a file restarting at end of local file. + put a file restarting at end of local file ****************************************************************************/ - static int cmd_reput(void) { pstring local_name; pstring remote_name; - pstring buf; + fstring buf; char *p = buf; SMB_STRUCT_STAT st; @@ -2010,151 +2206,24 @@ static int cmd_reput(void) return do_put(remote_name, local_name, True); } -/**************************************************************************** - List a share name. - ****************************************************************************/ - -static void browse_fn(const char *name, uint32 m, - const char *comment, void *state) -{ - fstring typestr; - - *typestr=0; - - switch (m) - { - case STYPE_DISKTREE: - fstrcpy(typestr,"Disk"); break; - case STYPE_PRINTQ: - fstrcpy(typestr,"Printer"); break; - case STYPE_DEVICE: - fstrcpy(typestr,"Device"); break; - case STYPE_IPC: - fstrcpy(typestr,"IPC"); break; - } - /* FIXME: If the remote machine returns non-ascii characters - in any of these fields, they can corrupt the output. We - should remove them. */ - if (!grepable) { - d_printf("\t%-15s %-10.10s%s\n", - name,typestr,comment); - } else { - d_printf ("%s|%s|%s\n",typestr,name,comment); - } -} /**************************************************************************** - Try and browse available connections on a host. +try and browse available connections on a host ****************************************************************************/ - static BOOL browse_host(BOOL sort) { - int ret; - if (!grepable) { - d_printf("\n\tSharename Type Comment\n"); - d_printf("\t--------- ---- -------\n"); - } - - if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1) - d_printf("Error returning browse list: %s\n", cli_errstr(cli)); - - return (ret != -1); -} - -/**************************************************************************** - List a server name. -****************************************************************************/ - -static void server_fn(const char *name, uint32 m, - const char *comment, void *state) -{ - - if (!grepable){ - d_printf("\t%-16s %s\n", name, comment); - } else { - d_printf("%s|%s|%s\n",(char *)state, name, comment); - } -} - -/**************************************************************************** - Try and browse available connections on a host. -****************************************************************************/ - -static BOOL list_servers(const char *wk_grp) -{ - if (!cli->server_domain) - return False; - - if (!grepable) { - d_printf("\n\tServer Comment\n"); - d_printf("\t--------- -------\n"); - }; - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, - "Server"); - - if (!grepable) { - d_printf("\n\tWorkgroup Master\n"); - d_printf("\t--------- -------\n"); - }; - - cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, - server_fn, "Workgroup"); - return True; -} - -/**************************************************************************** - Print or set current VUID -****************************************************************************/ - -static int cmd_vuid(void) -{ - fstring buf; - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { - d_printf("Current VUID is %d\n", cli->vuid); - return 0; - } + d_printf("REWRITE: host browsing not implemented\n"); - cli->vuid = atoi(buf); - return 0; + return False; } /**************************************************************************** - Setup a new VUID, by issuing a session setup +try and browse available connections on a host ****************************************************************************/ - -static int cmd_logon(void) +static BOOL list_servers(char *wk_grp) { - pstring l_username, l_password; - pstring buf,buf2; - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { - d_printf("logon <username> [<password>]\n"); - return 0; - } - - pstrcpy(l_username, buf); - - if (!next_token_nr(NULL,buf2,NULL,sizeof(buf))) { - char *pass = getpass("Password: "); - if (pass) { - pstrcpy(l_password, pass); - got_pass = 1; - } - } else { - pstrcpy(l_password, buf2); - } - - if (!cli_session_setup(cli, l_username, - l_password, strlen(l_password), - l_password, strlen(l_password), - lp_workgroup())) { - d_printf("session setup failed: %s\n", cli_errstr(cli)); - return -1; - } - - d_printf("Current VUID is %d\n", cli->vuid); - return 0; + d_printf("REWRITE: list servers not implemented\n"); + return False; } /* Some constants for completing filename arguments */ @@ -2174,9 +2243,12 @@ static struct int (*fn)(void); const char *description; char compl_args[2]; /* Completion argument info */ -} commands[] = { +} commands[] = +{ {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}}, {"altname",cmd_altname,"<file> show alt name",{COMPL_NONE,COMPL_NONE}}, + {"acl",cmd_acl,"<file> show file ACL",{COMPL_NONE,COMPL_NONE}}, + {"allinfo",cmd_allinfo,"<file> show all possible info about a file",{COMPL_NONE,COMPL_NONE}}, {"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",{COMPL_NONE,COMPL_NONE}}, {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}}, {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}}, @@ -2184,11 +2256,11 @@ static struct {"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_REMOTE}}, {"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_REMOTE}}, {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}}, + {"deltree",cmd_deltree,"<dir> delete a whole directory tree",{COMPL_REMOTE,COMPL_NONE}}, {"dir",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}}, {"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}}, {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}}, {"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}}, - {"hardlink",cmd_hardlink,"<src> <dest> create a Windows hard link",{COMPL_REMOTE,COMPL_REMOTE}}, {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}}, {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}}, {"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}}, @@ -2223,20 +2295,18 @@ static struct {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}}, {"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}}, {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}}, - {"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}}, - {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}}, /* Yes, this must be here, see crh's comment above. */ {"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}}, {NULL,NULL,NULL,{COMPL_NONE,COMPL_NONE}} }; -/******************************************************************* - Lookup a command string in the list of commands, including - abbreviations. -******************************************************************/ -static int process_tok(pstring tok) +/******************************************************************* + lookup a command string in the list of commands, including + abbreviations + ******************************************************************/ +static int process_tok(fstring tok) { int i = 0, matches = 0; int cmd=0; @@ -2263,13 +2333,12 @@ static int process_tok(pstring tok) } /**************************************************************************** - Help. +help ****************************************************************************/ - static int cmd_help(void) { int i=0,j; - pstring buf; + fstring buf; if (next_token_nr(NULL,buf,NULL,sizeof(buf))) { if ((i = process_tok(buf)) >= 0) @@ -2287,9 +2356,8 @@ static int cmd_help(void) } /**************************************************************************** - Process a -c command string. +process a -c command string ****************************************************************************/ - static int process_command_string(char *cmd) { pstring line; @@ -2306,7 +2374,7 @@ static int process_command_string(char *cmd) while (cmd[0] != '\0') { char *p; - pstring tok; + fstring tok; int i; if ((p = strchr_m(cmd, ';')) == 0) { @@ -2314,8 +2382,7 @@ static int process_command_string(char *cmd) line[1000] = '\0'; cmd += strlen(cmd); } else { - if (p - cmd > 999) - p = cmd + 999; + if (p - cmd > 999) p = cmd + 999; strncpy(line, cmd, p - cmd); line[p - cmd] = '\0'; cmd = p + 1; @@ -2352,7 +2419,7 @@ static void completion_remote_filter(file_info *f, const char *mask, void *state completion_remote_t *info = (completion_remote_t *)state; if ((info->count < MAX_COMPLETIONS - 1) && (strncmp(info->text, f->name, info->len) == 0) && (strcmp(f->name, ".") != 0) && (strcmp(f->name, "..") != 0)) { - if ((info->dirmask[0] == 0) && !(f->mode & aDIR)) + if ((info->dirmask[0] == 0) && !(f->mode & FILE_ATTRIBUTE_DIRECTORY)) info->matches[info->count] = strdup(f->name); else { pstring tmp; @@ -2362,13 +2429,13 @@ static void completion_remote_filter(file_info *f, const char *mask, void *state else tmp[0] = 0; pstrcat(tmp, f->name); - if (f->mode & aDIR) + if (f->mode & FILE_ATTRIBUTE_DIRECTORY) pstrcat(tmp, "/"); info->matches[info->count] = strdup(tmp); } if (info->matches[info->count] == NULL) return; - if (f->mode & aDIR) + if (f->mode & FILE_ATTRIBUTE_DIRECTORY) smb_readline_ca_char(0); if (info->count == 1) @@ -2386,12 +2453,10 @@ static char **remote_completion(const char *text, int len) int i; completion_remote_t info = { "", NULL, 1, 0, NULL, 0 }; - /* can't have non-static intialisation on Sun CC, so do it - at run time here */ info.samelen = len; info.text = text; info.len = len; - + if (len >= PATH_MAX) return(NULL); @@ -2408,11 +2473,13 @@ static char **remote_completion(const char *text, int len) if (i > 0) { strncpy(info.dirmask, text, i+1); info.dirmask[i+1] = 0; - pstr_sprintf(dirmask, "%s%*s*", cur_dir, i-1, text); + snprintf(dirmask, sizeof(dirmask), "%s%*s*", cur_dir, i-1, text); } else - pstr_sprintf(dirmask, "%s*", cur_dir); + snprintf(dirmask, sizeof(dirmask), "%s*", cur_dir); - if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0) + if (cli_list(cli->tree, dirmask, + FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, + completion_remote_filter, &info) < 0) goto cleanup; if (info.count == 2) @@ -2510,18 +2577,18 @@ static char **completion_fn(const char *text, int start, int end) return matches; cleanup: - for (i = 0; i < count; i++) + while (i >= 0) { free(matches[i]); - + i--; + } free(matches); return NULL; } } /**************************************************************************** - Make sure we swallow keepalives during idle time. +make sure we swallow keepalives during idle time ****************************************************************************/ - static void readline_callback(void) { fd_set fds; @@ -2531,46 +2598,49 @@ static void readline_callback(void) t = time(NULL); - if (t - last_t < 5) - return; + if (t - last_t < 5) return; last_t = t; again: - - if (cli->fd == -1) + if (cli->transport->socket->fd == -1) return; FD_ZERO(&fds); - FD_SET(cli->fd,&fds); + FD_SET(cli->transport->socket->fd, &fds); timeout.tv_sec = 0; timeout.tv_usec = 0; - sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout); + sys_select_intr(cli->transport->socket->fd+1,&fds,NULL,NULL,&timeout); - /* We deliberately use receive_smb instead of + /* We deliberately use cli_swallow_keepalives instead of client_receive_smb as we want to receive session keepalives and then drop them here. */ - if (FD_ISSET(cli->fd,&fds)) { - receive_smb(cli->fd,cli->inbuf,0); + if (FD_ISSET(cli->transport->socket->fd, &fds)) { + if (!cli_request_receive_next(cli->transport)) { + d_printf("Lost connection to server\n"); + exit(1); + } goto again; } - - cli_chkpath(cli, "\\"); + + if (cli->tree) { + cli_chkpath(cli->tree, "\\"); + } } + /**************************************************************************** - Process commands on stdin. +process commands on stdin ****************************************************************************/ - static void process_stdin(void) { const char *ptr; while (1) { - pstring tok; - pstring the_prompt; + fstring tok; + fstring the_prompt; char *cline; pstring line; int i; @@ -2603,21 +2673,21 @@ static void process_stdin(void) } } + /***************************************************** - Return a connection to a server. +return a connection to a server *******************************************************/ - static struct cli_state *do_connect(const char *server, const char *share) { struct cli_state *c; struct nmb_name called, calling; const char *server_n; struct in_addr ip; - pstring servicename; + fstring servicename; char *sharename; /* make a copy so we don't modify the global string 'service' */ - pstrcpy(servicename, share); + fstrcpy(servicename, share); sharename = servicename; if (*sharename == '\\') { server = sharename+2; @@ -2627,11 +2697,13 @@ static struct cli_state *do_connect(const char *server, const char *share) sharename++; } + asprintf(&sharename, "\\\\%s\\%s", server, sharename); + server_n = server; zero_ip(&ip); - make_nmb_name(&calling, global_myname(), 0x0); + make_nmb_name(&calling, lp_netbios_name(), 0x0); make_nmb_name(&called , server, name_type); again: @@ -2639,21 +2711,15 @@ static struct cli_state *do_connect(const char *server, const char *share) if (have_ip) ip = dest_ip; /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) || - !cli_connect(c, server_n, &ip)) { + if (!(c=cli_state_init()) || !cli_socket_connect(c, server_n, &ip)) { d_printf("Connection to %s failed\n", server_n); return NULL; } - c->protocol = max_protocol; - c->use_kerberos = use_kerberos; - cli_setup_signing_state(c, cmdline_auth_info.signing_state); - - - if (!cli_session_request(c, &calling, &called)) { + if (!cli_transport_establish(c, &calling, &called)) { char *p; d_printf("session request to %s failed (%s)\n", - called.name, cli_errstr(c)); + called.name, cli_errstr(c->tree)); cli_shutdown(c); if ((p=strchr_m(called.name, '.'))) { *p = 0; @@ -2668,49 +2734,35 @@ static struct cli_state *do_connect(const char *server, const char *share) DEBUG(4,(" session request ok\n")); - if (!cli_negprot(c)) { + if (NT_STATUS_IS_ERR(cli_negprot(c))) { d_printf("protocol negotiation failed\n"); cli_shutdown(c); return NULL; } if (!got_pass) { - char *pass = getpass("Password: "); + const char *pass = getpass("Password: "); if (pass) { pstrcpy(password, pass); - got_pass = 1; } } - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - lp_workgroup())) { + if (NT_STATUS_IS_ERR(cli_session_setup(c, username, password, + lp_workgroup()))) { /* if a password was not supplied then try again with a null username */ if (password[0] || !username[0] || use_kerberos || - !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) { - d_printf("session setup failed: %s\n", cli_errstr(c)); - if (NT_STATUS_V(cli_nt_error(c)) == - NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) - d_printf("did you forget to run kinit?\n"); + NT_STATUS_IS_ERR(cli_session_setup(c, "", "", lp_workgroup()))) { + d_printf("session setup failed: %s\n", cli_errstr(c->tree)); cli_shutdown(c); return NULL; } d_printf("Anonymous login successful\n"); } - if (*c->server_domain) { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - c->server_domain,c->server_os,c->server_type)); - } else if (*c->server_os || *c->server_type){ - DEBUG(1,("OS=[%s] Server=[%s]\n", - c->server_os,c->server_type)); - } DEBUG(4,(" session setup ok\n")); - if (!cli_send_tconX(c, sharename, "?????", - password, strlen(password)+1)) { - d_printf("tree connect failed: %s\n", cli_errstr(c)); + if (NT_STATUS_IS_ERR(cli_send_tconX(c, sharename, "?????", password))) { + d_printf("tree connect failed: %s\n", cli_errstr(c->tree)); cli_shutdown(c); return NULL; } @@ -2720,10 +2772,10 @@ static struct cli_state *do_connect(const char *server, const char *share) return c; } + /**************************************************************************** - Process commands from the client. + process commands from the client ****************************************************************************/ - static int process(char *base_directory) { int rc = 0; @@ -2746,9 +2798,8 @@ static int process(char *base_directory) } /**************************************************************************** - Handle a -L query. +handle a -L query ****************************************************************************/ - static int do_host_query(char *query_host) { cli = do_connect(query_host, "IPC$"); @@ -2756,22 +2807,6 @@ static int do_host_query(char *query_host) return 1; browse_host(True); - - if (port != 139) { - - /* Workgroups simply don't make sense over anything - else but port 139... */ - - cli_shutdown(cli); - port = 139; - cli = do_connect(query_host, "IPC$"); - } - - if (cli == NULL) { - d_printf("NetBIOS over TCP disabled -- no workgroup available\n"); - return 1; - } - list_servers(lp_workgroup()); cli_shutdown(cli); @@ -2781,9 +2816,8 @@ static int do_host_query(char *query_host) /**************************************************************************** - Handle a tar operation. +handle a tar operation ****************************************************************************/ - static int do_tar_op(char *base_directory) { int ret; @@ -2807,9 +2841,8 @@ static int do_tar_op(char *base_directory) } /**************************************************************************** - Handle a message operation. +handle a message operation ****************************************************************************/ - static int do_message_op(void) { struct in_addr ip; @@ -2817,23 +2850,22 @@ static int do_message_op(void) fstring server_name; char name_type_hex[10]; - make_nmb_name(&calling, global_myname(), 0x0); + make_nmb_name(&calling, lp_netbios_name(), 0x0); make_nmb_name(&called , desthost, name_type); fstrcpy(server_name, desthost); snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type); fstrcat(server_name, name_type_hex); - zero_ip(&ip); + zero_ip(&ip); if (have_ip) ip = dest_ip; - if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, port) != port) || - !cli_connect(cli, server_name, &ip)) { + if (!(cli=cli_state_init()) || !cli_socket_connect(cli, server_name, &ip)) { d_printf("Connection to %s failed\n", desthost); return 1; } - if (!cli_session_request(cli, &calling, &called)) { + if (!cli_transport_establish(cli, &calling, &called)) { d_printf("session request failed\n"); cli_shutdown(cli); return 1; @@ -2846,29 +2878,46 @@ static int do_message_op(void) } +/** + * Process "-L hostname" option. + * + * We don't actually do anything yet -- we just stash the name in a + * global variable and do the query when all options have been read. + **/ +static void remember_query_host(const char *arg, + pstring query_host) +{ + char *slash; + + while (*arg == '\\' || *arg == '/') + arg++; + pstrcpy(query_host, arg); + if ((slash = strchr(query_host, '/')) + || (slash = strchr(query_host, '\\'))) { + *slash = 0; + } +} + + /**************************************************************************** main program ****************************************************************************/ - int main(int argc,char *argv[]) { - extern BOOL AllowDebugChange; - extern BOOL override_logfile; - pstring base_directory; + fstring base_directory; int opt; pstring query_host; BOOL message = False; extern char tar_type; pstring term_code; - static const char *new_name_resolve_order = NULL; poptContext pc; char *p; int rc = 0; - fstring new_workgroup; + TALLOC_CTX *mem_ctx; struct poptOption long_options[] = { POPT_AUTOHELP - { "name-resolve", 'R', POPT_ARG_STRING, &new_name_resolve_order, 'R', "Use these name resolution services only", "NAME-RESOLVE-ORDER" }, + { "name-resolve", 'R', POPT_ARG_STRING, NULL, 'R', "Use these name resolution services only", "NAME-RESOLVE-ORDER" }, { "message", 'M', POPT_ARG_STRING, NULL, 'M', "Send message", "HOST" }, { "ip-address", 'I', POPT_ARG_STRING, NULL, 'I', "Use this IP to connect to", "IP" }, { "stderr", 'E', POPT_ARG_NONE, NULL, 'E', "Write messages to stderr instead of stdout" }, @@ -2878,9 +2927,8 @@ static int do_message_op(void) { "tar", 'T', POPT_ARG_STRING, NULL, 'T', "Command line tar", "<c|x>IXFqgbNan" }, { "directory", 'D', POPT_ARG_STRING, NULL, 'D', "Start from directory", "DIR" }, { "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" }, - { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" }, + { "send-buffer", 'b', POPT_ARG_INT, NULL, 'b', "Changes the transmit/send buffer", "BYTES" }, { "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" }, - { "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" }, POPT_COMMON_SAMBA POPT_COMMON_CONNECTION POPT_COMMON_CREDENTIALS @@ -2896,18 +2944,19 @@ static int do_message_op(void) *query_host = 0; *base_directory = 0; - - /* initialize the workgroup name so we can determine whether or - not it was set by a command line option */ - - set_global_myworkgroup( "" ); - /* set default debug level to 0 regardless of what smb.conf sets */ - setup_logging( "smbclient", True ); - DEBUGLEVEL_CLASS[DBGC_ALL] = 1; - dbf = x_stderr; - x_setbuf( x_stderr, NULL ); + setup_logging(argv[0],DEBUG_STDOUT); + mem_ctx = talloc_init("client.c/main"); + if (!mem_ctx) { + d_printf("\nclient.c: Not enough memory\n"); + exit(1); + } + if (!lp_load(dyn_CONFIGFILE,True,False,False)) { + fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", + argv[0], dyn_CONFIGFILE); + } + pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "service <password>"); @@ -2923,91 +2972,51 @@ static int do_message_op(void) */ name_type = 0x03; pstrcpy(desthost,poptGetOptArg(pc)); - if( 0 == port ) - port = 139; + if( 0 == port ) port = 139; message = True; break; case 'I': { - dest_ip = *interpret_addr2(poptGetOptArg(pc)); + dest_ip = *interpret_addr2(mem_ctx, poptGetOptArg(pc)); if (is_zero_ip(dest_ip)) exit(1); have_ip = True; } break; case 'E': - dbf = x_stderr; - display_set_stderr(); + setup_logging("client", DEBUG_STDERR); break; case 'L': - pstrcpy(query_host, poptGetOptArg(pc)); + remember_query_host(poptGetOptArg(pc), query_host); break; case 't': pstrcpy(term_code, poptGetOptArg(pc)); break; case 'm': - max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol); + lp_set_cmdline("max protocol", poptGetOptArg(pc)); + break; + case 'R': + lp_set_cmdline("name resolve order", poptGetOptArg(pc)); break; case 'T': - /* We must use old option processing for this. Find the - * position of the -T option in the raw argv[]. */ - { - int i, optnum; - for (i = 1; i < argc; i++) { - if (strncmp("-T", argv[i],2)==0) - break; - } - i++; - if (!(optnum = tar_parseargs(argc, argv, poptGetOptArg(pc), i))) { - poptPrintUsage(pc, stderr, 0); - exit(1); - } - /* Now we must eat (optnum - i) options - they have - * been processed by tar_parseargs(). - */ - optnum -= i; - for (i = 0; i < optnum; i++) - poptGetOptArg(pc); + if (!tar_parseargs(argc, argv, poptGetOptArg(pc), optind)) { + poptPrintUsage(pc, stderr, 0); + exit(1); } break; case 'D': - pstrcpy(base_directory,poptGetOptArg(pc)); + fstrcpy(base_directory,poptGetOptArg(pc)); break; - case 'g': - grepable=True; + case 'b': + io_bufsize = MAX(1, atoi(poptGetOptArg(pc))); break; } } poptGetArg(pc); - /* - * Don't load debug level from smb.conf. It should be - * set by cmdline arg or remain default (0) - */ - AllowDebugChange = False; - - /* save the workgroup... - - FIXME!! do we need to do this for other options as well - (or maybe a generic way to keep lp_load() from overwriting - everything)? */ - - fstrcpy( new_workgroup, lp_workgroup() ); - - if ( override_logfile ) - setup_logging( lp_logfile(), False ); - - if (!lp_load(dyn_CONFIGFILE,True,False,False)) { - fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", - argv[0], dyn_CONFIGFILE); - } - load_interfaces(); - - if ( strlen(new_workgroup) != 0 ) - set_global_myworkgroup( new_workgroup ); if(poptPeekArg(pc)) { pstrcpy(service,poptGetArg(pc)); @@ -3021,15 +3030,12 @@ static int do_message_op(void) } } - if (poptPeekArg(pc) && !cmdline_auth_info.got_pass) { + if (poptPeekArg(pc)) { cmdline_auth_info.got_pass = True; pstrcpy(cmdline_auth_info.password,poptGetArg(pc)); } - init_names(); - - if(new_name_resolve_order) - lp_set_name_resolve_order(new_name_resolve_order); + /*init_names(); */ if (!tar_type && !*query_host && !*service && !message) { poptPrintUsage(pc, stderr, 0); @@ -3040,37 +3046,26 @@ static int do_message_op(void) pstrcpy(username, cmdline_auth_info.username); pstrcpy(password, cmdline_auth_info.password); - use_kerberos = cmdline_auth_info.use_kerberos; got_pass = cmdline_auth_info.got_pass; - DEBUG(3,("Client started (version %s).\n", SAMBA_VERSION_STRING)); + DEBUG( 3, ( "Client started (version %s).\n", SAMBA_VERSION_STRING ) ); + talloc_destroy(mem_ctx); if (tar_type) { if (cmdstr) process_command_string(cmdstr); return do_tar_op(base_directory); } - if (*query_host) { - char *qhost = query_host; - char *slash; - - while (*qhost == '\\' || *qhost == '/') - qhost++; - - if ((slash = strchr_m(qhost, '/')) - || (slash = strchr_m(qhost, '\\'))) { - *slash = 0; - } - - if ((p=strchr_m(qhost, '#'))) { - *p = 0; - p++; - sscanf(p, "%x", &name_type); - } + if ((p=strchr_m(query_host,'#'))) { + *p = 0; + p++; + sscanf(p, "%x", &name_type); + } - return do_host_query(qhost); + if (*query_host) { + return do_host_query(query_host); } if (message) { diff --git a/source/client/clitar.c b/source/client/clitar.c index e43b3e4cc50..da91ba4bebb 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -37,29 +37,33 @@ #include "includes.h" #include "clitar.h" -#include "../client/client_proto.h" static int clipfind(char **aret, int ret, char *tok); +void dos_clean_name(char *s); typedef struct file_info_struct file_info2; -struct file_info_struct { - SMB_BIG_UINT size; - uint16 mode; - uid_t uid; - gid_t gid; - /* These times are normally kept in GMT */ - time_t mtime; - time_t atime; - time_t ctime; - char *name; /* This is dynamically allocate */ - - file_info2 *next, *prev; /* Used in the stack ... */ +struct file_info_struct +{ + SMB_BIG_UINT size; + uint16 mode; + uid_t uid; + gid_t gid; + /* These times are normally kept in GMT */ + time_t mtime; + time_t atime; + time_t ctime; + char *name; /* This is dynamically allocate */ + + file_info2 *next, *prev; /* Used in the stack ... */ + }; -typedef struct { - file_info2 *top; - int items; +typedef struct +{ + file_info2 *top; + int items; + } stack; #define SEPARATORS " \t\n\r" @@ -70,7 +74,7 @@ extern struct cli_state *cli; #define ATTRSET 1 #define ATTRRESET 0 -static uint16 attribute = aDIR | aSYSTEM | aHIDDEN; +static uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; #ifndef CLIENT_TIMEOUT #define CLIENT_TIMEOUT (30*1000) @@ -122,7 +126,7 @@ static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t static void do_atar(char *rname,char *lname,file_info *finfo1); static void do_tar(file_info *finfo); static void oct_it(SMB_BIG_UINT value, int ndgs, char *p); -static void fixtarname(char *tptr, const char *fp, size_t l); +static void fixtarname(char *tptr, const char *fp, int l); static int dotarbuf(int f, char *b, int n); static void dozerobuf(int f, int n); static void dotareof(int f); @@ -141,337 +145,325 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first); /******************************************************************* Create a string of size size+1 (for the null) *******************************************************************/ - static char *string_create_s(int size) { - char *tmp; + char *tmp; - tmp = (char *)malloc(size+1); + tmp = (char *)malloc(size+1); - if (tmp == NULL) { - DEBUG(0, ("Out of memory in string_create_s\n")); - } + if (tmp == NULL) { + + DEBUG(0, ("Out of memory in string_create_s\n")); + + } + + return(tmp); - return(tmp); } /**************************************************************************** Write a tar header to buffer ****************************************************************************/ - static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime, const char *amode, unsigned char ftype) { - union hblock hb; - int i, chk, l; - char *jp; + union hblock hb; + int i, chk, l; + char *jp; - DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname)); + DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname)); - memset(hb.dummy, 0, sizeof(hb.dummy)); + memset(hb.dummy, 0, sizeof(hb.dummy)); - l=strlen(aname); - /* We will be prepending a '.' in fixtarheader so use +2 to - * take care of the . and terminating zero. JRA. - */ - if (l+2 >= NAMSIZ) { - /* write a GNU tar style long header */ - char *b; - b = (char *)malloc(l+TBLOCK+100); - if (!b) { - DEBUG(0,("out of memory\n")); - exit(1); - } - writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L'); - memset(b, 0, l+TBLOCK+100); - fixtarname(b, aname, l+2); - i = strlen(b)+1; - DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b))); - dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1)); - SAFE_FREE(b); - } - - fixtarname(hb.dbuf.name, aname, (l+2 >= NAMSIZ) ? NAMSIZ : l + 2); - - if (lowercase) - strlower_m(hb.dbuf.name); - - /* write out a "standard" tar format header */ - - hb.dbuf.name[NAMSIZ-1]='\0'; - safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1); - oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid); - oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid); - oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size); - if (size > (SMB_BIG_UINT)077777777777LL) { - - /* This is a non-POSIX compatible extention to store files - greater than 8GB. */ - - memset(hb.dbuf.size, 0, 4); - hb.dbuf.size[0]=128; - for (i = 8, jp=(char*)&size; i; i--) - hb.dbuf.size[i+3] = *(jp++); - } - oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime); - memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum)); - memset(hb.dbuf.linkname, 0, NAMSIZ); - hb.dbuf.linkflag=ftype; + l=strlen(aname); + if (l >= NAMSIZ - 1) { + /* write a GNU tar style long header */ + char *b; + b = (char *)malloc(l+TBLOCK+100); + if (!b) { + DEBUG(0,("out of memory\n")); + exit(1); + } + writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L'); + memset(b, 0, l+TBLOCK+100); + fixtarname(b, aname, l); + i = strlen(b)+1; + DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b))); + dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1)); + SAFE_FREE(b); + } + + /* use l + 1 to do the null too */ + fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1); + + if (lowercase) + strlower(hb.dbuf.name); + + /* write out a "standard" tar format header */ + + hb.dbuf.name[NAMSIZ-1]='\0'; + safe_strcpy(hb.dbuf.mode, amode, strlen(amode)); + oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid); + oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid); + oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size); + oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime); + memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum)); + memset(hb.dbuf.linkname, 0, NAMSIZ); + hb.dbuf.linkflag=ftype; - for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) - chk+=(0xFF & *jp++); + for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) chk+=(0xFF & *jp++); - oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum); - hb.dbuf.chksum[6] = '\0'; + oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum); + hb.dbuf.chksum[6] = '\0'; - (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy)); + (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy)); } /**************************************************************************** Read a tar header into a hblock structure, and validate ***************************************************************************/ - static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix) { - long chk, fchk; - int i; - char *jp; + long chk, fchk; + int i; + char *jp; - /* - * read in a "standard" tar format header - we're not that interested - * in that many fields, though - */ + /* + * read in a "standard" tar format header - we're not that interested + * in that many fields, though + */ - /* check the checksum */ - for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) - chk+=(0xFF & *jp++); + /* check the checksum */ + for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) chk+=(0xFF & *jp++); - if (chk == 0) - return chk; + if (chk == 0) + return chk; - /* compensate for blanks in chksum header */ - for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;) - chk-=(0xFF & *jp++); + /* compensate for blanks in chksum header */ + for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;) + chk-=(0xFF & *jp++); - chk += ' ' * sizeof(hb->dbuf.chksum); + chk += ' ' * sizeof(hb->dbuf.chksum); - fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum)); + fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum)); - DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n", - chk, fchk, hb->dbuf.chksum)); + DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n", + chk, fchk, hb->dbuf.chksum)); - if (fchk != chk) { - DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk)); - dump_data(5, (char *)hb - TBLOCK, TBLOCK *3); - return -1; - } + if (fchk != chk) + { + DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk)); + dump_data(5, (char *)hb - TBLOCK, TBLOCK *3); + return -1; + } - if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) { - DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name)); - return(-1); - } + if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) { - safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3); - - /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */ - unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name, - strlen(hb->dbuf.name) + 1, True); - - /* can't handle some links at present */ - if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) { - if (hb->dbuf.linkflag == 0) { - DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n", - finfo->name)); - } else { - if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */ - /* Do nothing here at the moment. do_tarput will handle this - as long as the longlink gets back to it, as it has to advance - the buffer pointer, etc */ - } else { - DEBUG(0, ("this tar file appears to contain some kind \ -of link other than a GNUtar Longlink - ignoring\n")); - return -2; - } - } - } - - if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) || - (*(finfo->name+strlen(finfo->name)-1) == '\\')) { - finfo->mode=aDIR; - } else { - finfo->mode=0; /* we don't care about mode at the moment, we'll - * just make it a regular file */ - } + DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name)); + return(-1); - /* - * Bug fix by richard@sj.co.uk - * - * REC: restore times correctly (as does tar) - * We only get the modification time of the file; set the creation time - * from the mod. time, and the access time to current time - */ - finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8); - finfo->atime = time(NULL); - finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size)); + } - return True; + safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3); + + /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */ + unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name, + strlen(hb->dbuf.name) + 1, True); + + /* can't handle some links at present */ + if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) { + if (hb->dbuf.linkflag == 0) { + DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n", + finfo->name)); + } else { + if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */ + /* Do nothing here at the moment. do_tarput will handle this + as long as the longlink gets back to it, as it has to advance + the buffer pointer, etc */ + + } else { + DEBUG(0, ("this tar file appears to contain some kind of link other than a GNUtar Longlink - ignoring\n")); + return -2; + } + } + } + + if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) + || (*(finfo->name+strlen(finfo->name)-1) == '\\')) + { + finfo->mode=FILE_ATTRIBUTE_DIRECTORY; + } + else + finfo->mode=0; /* we don't care about mode at the moment, we'll + * just make it a regular file */ + /* + * Bug fix by richard@sj.co.uk + * + * REC: restore times correctly (as does tar) + * We only get the modification time of the file; set the creation time + * from the mod. time, and the access time to current time + */ + finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8); + finfo->atime = time(NULL); + finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size)); + + return True; } /**************************************************************************** Write out the tar buffer to tape or wherever ****************************************************************************/ - static int dotarbuf(int f, char *b, int n) { - int fail=1, writ=n; - - if (dry_run) { - return writ; - } - /* This routine and the next one should be the only ones that do write()s */ - if (tp + n >= tbufsiz) { - int diff; - - diff=tbufsiz-tp; - memcpy(tarbuf + tp, b, diff); - fail=fail && (1+write(f, tarbuf, tbufsiz)); - n-=diff; - b+=diff; - tp=0; - - while (n >= tbufsiz) { - fail=fail && (1 + write(f, b, tbufsiz)); - n-=tbufsiz; - b+=tbufsiz; - } - } - - if (n>0) { - memcpy(tarbuf+tp, b, n); - tp+=n; + int fail=1, writ=n; + + if (dry_run) { + return writ; + } + /* This routine and the next one should be the only ones that do write()s */ + if (tp + n >= tbufsiz) + { + int diff; + + diff=tbufsiz-tp; + memcpy(tarbuf + tp, b, diff); + fail=fail && (1+write(f, tarbuf, tbufsiz)); + n-=diff; + b+=diff; + tp=0; + + while (n >= tbufsiz) + { + fail=fail && (1 + write(f, b, tbufsiz)); + n-=tbufsiz; + b+=tbufsiz; } + } + if (n>0) { + memcpy(tarbuf+tp, b, n); + tp+=n; + } - return(fail ? writ : 0); + return(fail ? writ : 0); } /**************************************************************************** Write zeros to buffer / tape ****************************************************************************/ - static void dozerobuf(int f, int n) { - /* short routine just to write out n zeros to buffer - - * used to round files to nearest block - * and to do tar EOFs */ + /* short routine just to write out n zeros to buffer - + * used to round files to nearest block + * and to do tar EOFs */ - if (dry_run) - return; + if (dry_run) + return; - if (n+tp >= tbufsiz) { - memset(tarbuf+tp, 0, tbufsiz-tp); - write(f, tarbuf, tbufsiz); - memset(tarbuf, 0, (tp+=n-tbufsiz)); - } else { - memset(tarbuf+tp, 0, n); - tp+=n; - } + if (n+tp >= tbufsiz) + { + memset(tarbuf+tp, 0, tbufsiz-tp); + + write(f, tarbuf, tbufsiz); + memset(tarbuf, 0, (tp+=n-tbufsiz)); + } + else + { + memset(tarbuf+tp, 0, n); + tp+=n; + } } /**************************************************************************** Malloc tape buffer ****************************************************************************/ - static void initarbuf(void) { - /* initialize tar buffer */ - tbufsiz=blocksize*TBLOCK; - tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */ + /* initialize tar buffer */ + tbufsiz=blocksize*TBLOCK; + tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */ - /* reset tar buffer pointer and tar file counter and total dumped */ - tp=0; ntarf=0; ttarf=0; + /* reset tar buffer pointer and tar file counter and total dumped */ + tp=0; ntarf=0; ttarf=0; } /**************************************************************************** Write two zero blocks at end of file ****************************************************************************/ - static void dotareof(int f) { - SMB_STRUCT_STAT stbuf; - /* Two zero blocks at end of file, write out full buffer */ + SMB_STRUCT_STAT stbuf; + /* Two zero blocks at end of file, write out full buffer */ - if (dry_run) - return; + if (dry_run) + return; - (void) dozerobuf(f, TBLOCK); - (void) dozerobuf(f, TBLOCK); + (void) dozerobuf(f, TBLOCK); + (void) dozerobuf(f, TBLOCK); - if (sys_fstat(f, &stbuf) == -1) { - DEBUG(0, ("Couldn't stat file handle\n")); - return; - } + if (sys_fstat(f, &stbuf) == -1) + { + DEBUG(0, ("Couldn't stat file handle\n")); + return; + } - /* Could be a pipe, in which case S_ISREG should fail, - * and we should write out at full size */ - if (tp > 0) - write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz); + /* Could be a pipe, in which case S_ISREG should fail, + * and we should write out at full size */ + if (tp > 0) write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz); } /**************************************************************************** (Un)mangle DOS pathname, make nonabsolute ****************************************************************************/ - -static void fixtarname(char *tptr, const char *fp, size_t l) +static void fixtarname(char *tptr, const char *fp, int l) { /* add a '.' to start of file name, convert from ugly dos \'s in path * to lovely unix /'s :-} */ *tptr++='.'; - l--; - StrnCpy(tptr, fp, l-1); + safe_strcpy(tptr, fp, l); string_replace(tptr, '\\', '/'); } /**************************************************************************** Convert from decimal to octal string ****************************************************************************/ - static void oct_it (SMB_BIG_UINT value, int ndgs, char *p) { - /* Converts long to octal string, pads with leading zeros */ + /* Converts long to octal string, pads with leading zeros */ - /* skip final null, but do final space */ - --ndgs; - p[--ndgs] = ' '; + /* skip final null, but do final space */ + --ndgs; + p[--ndgs] = ' '; - /* Loop does at least one digit */ - do { - p[--ndgs] = '0' + (char) (value & 7); - value >>= 3; - } while (ndgs > 0 && value != 0); + /* Loop does at least one digit */ + do { + p[--ndgs] = '0' + (char) (value & 7); + value >>= 3; + } + while (ndgs > 0 && value != 0); - /* Do leading zeros */ - while (ndgs > 0) - p[--ndgs] = '0'; + /* Do leading zeros */ + while (ndgs > 0) + p[--ndgs] = '0'; } /**************************************************************************** Convert from octal string to long ***************************************************************************/ - static long unoct(char *p, int ndgs) { - long value=0; - /* Converts octal string to long, ignoring any non-digit */ + long value=0; + /* Converts octal string to long, ignoring any non-digit */ - while (--ndgs) { - if (isdigit((int)*p)) - value = (value << 3) | (long) (*p - '0'); + while (--ndgs) + { + if (isdigit((int)*p)) + value = (value << 3) | (long) (*p - '0'); - p++; - } + p++; + } - return value; + return value; } /**************************************************************************** @@ -479,86 +471,90 @@ Compare two strings in a slash insensitive way, allowing s1 to match s2 if s1 is an "initial" string (up to directory marker). Thus, if s2 is a file in any subdirectory of s1, declare a match. ***************************************************************************/ - static int strslashcmp(char *s1, char *s2) { - char *s1_0=s1; + char *s1_0=s1; - while(*s1 && *s2 && (*s1 == *s2 || tolower(*s1) == tolower(*s2) || - (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) { - s1++; s2++; - } + while(*s1 && *s2 && + (*s1 == *s2 + || tolower(*s1) == tolower(*s2) + || (*s1 == '\\' && *s2=='/') + || (*s1 == '/' && *s2=='\\'))) { + s1++; s2++; + } - /* if s1 has a trailing slash, it compared equal, so s1 is an "initial" - string of s2. - */ - if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) - return 0; + /* if s1 has a trailing slash, it compared equal, so s1 is an "initial" + string of s2. + */ + if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) return 0; - /* ignore trailing slash on s1 */ - if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) - return 0; + /* ignore trailing slash on s1 */ + if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0; - /* check for s1 is an "initial" string of s2 */ - if ((*s2 == '/' || *s2 == '\\') && !*s1) - return 0; + /* check for s1 is an "initial" string of s2 */ + if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0; - return *s1-*s2; + return *s1-*s2; } + /**************************************************************************** Ensure a remote path exists (make if necessary) ***************************************************************************/ - static BOOL ensurepath(char *fname) { - /* *must* be called with buffer ready malloc'ed */ - /* ensures path exists */ + /* *must* be called with buffer ready malloc'ed */ + /* ensures path exists */ - char *partpath, *ffname; - char *p=fname, *basehack; + char *partpath, *ffname; + char *p=fname, *basehack; - DEBUG(5, ( "Ensurepath called with: %s\n", fname)); + DEBUG(5, ( "Ensurepath called with: %s\n", fname)); - partpath = string_create_s(strlen(fname)); - ffname = string_create_s(strlen(fname)); + partpath = string_create_s(strlen(fname)); + ffname = string_create_s(strlen(fname)); - if ((partpath == NULL) || (ffname == NULL)){ - DEBUG(0, ("Out of memory in ensurepath: %s\n", fname)); - return(False); - } + if ((partpath == NULL) || (ffname == NULL)){ - *partpath = 0; + DEBUG(0, ("Out of memory in ensurepath: %s\n", fname)); + return(False); - /* fname copied to ffname so can strtok */ + } - safe_strcpy(ffname, fname, strlen(fname)); + *partpath = 0; - /* do a `basename' on ffname, so don't try and make file name directory */ - if ((basehack=strrchr_m(ffname, '\\')) == NULL) - return True; - else - *basehack='\0'; + /* fname copied to ffname so can strtok */ - p=strtok(ffname, "\\"); + safe_strcpy(ffname, fname, strlen(fname)); - while (p) { - safe_strcat(partpath, p, strlen(fname) + 1); + /* do a `basename' on ffname, so don't try and make file name directory */ + if ((basehack=strrchr_m(ffname, '\\')) == NULL) + return True; + else + *basehack='\0'; - if (!cli_chkpath(cli, partpath)) { - if (!cli_mkdir(cli, partpath)) { - DEBUG(0, ("Error mkdirhiering\n")); - return False; - } else { - DEBUG(3, ("mkdirhiering %s\n", partpath)); - } - } + p=strtok(ffname, "\\"); - safe_strcat(partpath, "\\", strlen(fname) + 1); - p = strtok(NULL,"/\\"); - } + while (p) + { + safe_strcat(partpath, p, strlen(fname) + 1); + + if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, partpath))) { + if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, partpath))) + { + DEBUG(0, ("Error mkdirhiering\n")); + return False; + } + else + DEBUG(3, ("mkdirhiering %s\n", partpath)); + + } + + safe_strcat(partpath, "\\", strlen(fname) + 1); + p = strtok(NULL,"/\\"); + } - return True; + return True; } static int padit(char *buf, int bufsize, int padsize) @@ -577,11 +573,13 @@ static int padit(char *buf, int bufsize, int padsize) return berr; } + static void do_setrattr(char *name, uint16 attr, int set) { uint16 oldattr; - if (!cli_getatr(cli, name, &oldattr, NULL, NULL)) return; + if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, name, &oldattr, NULL, NULL))) + return; if (set == ATTRSET) { attr |= oldattr; @@ -589,263 +587,275 @@ static void do_setrattr(char *name, uint16 attr, int set) attr = oldattr & ~attr; } - if (!cli_setatr(cli, name, attr, 0)) { - DEBUG(1,("setatr failed: %s\n", cli_errstr(cli))); + if (NT_STATUS_IS_ERR(cli_setatr(cli->tree, name, attr, 0))) { + DEBUG(1,("setatr failed: %s\n", cli_errstr(cli->tree))); } } + /**************************************************************************** append one remote file to the tar file ***************************************************************************/ - static void do_atar(char *rname,char *lname,file_info *finfo1) { - int fnum; - SMB_BIG_UINT nread=0; - char ftype; - file_info2 finfo; - BOOL close_done = False; - BOOL shallitime=True; - char data[65520]; - int read_size = 65520; - int datalen=0; - - struct timeval tp_start; - - GetTimeOfDay(&tp_start); - - ftype = '0'; /* An ordinary file ... */ - - if (finfo1) { - finfo.size = finfo1 -> size; - finfo.mode = finfo1 -> mode; - finfo.uid = finfo1 -> uid; - finfo.gid = finfo1 -> gid; - finfo.mtime = finfo1 -> mtime; - finfo.atime = finfo1 -> atime; - finfo.ctime = finfo1 -> ctime; - finfo.name = finfo1 -> name; - } else { - finfo.size = def_finfo.size; - finfo.mode = def_finfo.mode; - finfo.uid = def_finfo.uid; - finfo.gid = def_finfo.gid; - finfo.mtime = def_finfo.mtime; - finfo.atime = def_finfo.atime; - finfo.ctime = def_finfo.ctime; - finfo.name = def_finfo.name; - } - - if (dry_run) { - DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name, - (double)finfo.size)); - shallitime=0; - ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); - ntarf++; - return; - } - - fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE); - - dos_clean_name(rname); - - if (fnum == -1) { - DEBUG(0,("%s opening remote file %s (%s)\n", - cli_errstr(cli),rname, cur_dir)); - return; - } - - finfo.name = string_create_s(strlen(rname)); - if (finfo.name == NULL) { - DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n")); - return; - } - - safe_strcpy(finfo.name,rname, strlen(rname)); - if (!finfo1) { - if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) { - DEBUG(0, ("getattrE: %s\n", cli_errstr(cli))); - return; - } - finfo.ctime = finfo.mtime; - } - - DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode)); - - if (tar_inc && !(finfo.mode & aARCH)) { - DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name)); - shallitime=0; - } else if (!tar_system && (finfo.mode & aSYSTEM)) { - DEBUG(4, ("skipping %s - system bit is set\n", finfo.name)); - shallitime=0; - } else if (!tar_hidden && (finfo.mode & aHIDDEN)) { - DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name)); - shallitime=0; - } else { - DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s", - finfo.name, (double)finfo.size, lname)); + int fnum; + SMB_BIG_UINT nread=0; + char ftype; + file_info2 finfo; + BOOL close_done = False; + BOOL shallitime=True; + char data[65520]; + int read_size = 65520; + int datalen=0; + + struct timeval tp_start; + GetTimeOfDay(&tp_start); + + ftype = '0'; /* An ordinary file ... */ + + if (finfo1) { + finfo.size = finfo1 -> size; + finfo.mode = finfo1 -> mode; + finfo.uid = finfo1 -> uid; + finfo.gid = finfo1 -> gid; + finfo.mtime = finfo1 -> mtime; + finfo.atime = finfo1 -> atime; + finfo.ctime = finfo1 -> ctime; + finfo.name = finfo1 -> name; + } + else { + finfo.size = def_finfo.size; + finfo.mode = def_finfo.mode; + finfo.uid = def_finfo.uid; + finfo.gid = def_finfo.gid; + finfo.mtime = def_finfo.mtime; + finfo.atime = def_finfo.atime; + finfo.ctime = def_finfo.ctime; + finfo.name = def_finfo.name; + } + + if (dry_run) + { + DEBUG(3,("skipping file %s of size %12.0f bytes\n", + finfo.name, + (double)finfo.size)); + shallitime=0; + ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); + ntarf++; + return; + } + + fnum = cli_open(cli->tree, rname, O_RDONLY, DENY_NONE); + + dos_clean_name(rname); + + if (fnum == -1) { + DEBUG(0,("%s opening remote file %s (%s)\n", + cli_errstr(cli->tree),rname, cur_dir)); + return; + } + + finfo.name = string_create_s(strlen(rname)); + if (finfo.name == NULL) { + DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n")); + return; + } + + safe_strcpy(finfo.name,rname, strlen(rname)); + if (!finfo1) { + size_t size; + if (NT_STATUS_IS_ERR(cli_getattrE(cli->tree, fnum, &finfo.mode, &size, NULL, &finfo.atime, &finfo.mtime))) { + DEBUG(0, ("getattrE: %s\n", cli_errstr(cli->tree))); + return; + } + finfo.size = size; + finfo.ctime = finfo.mtime; + } + + DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode)); + + if (tar_inc && !(finfo.mode & FILE_ATTRIBUTE_ARCHIVE)) + { + DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name)); + shallitime=0; + } + else if (!tar_system && (finfo.mode & FILE_ATTRIBUTE_SYSTEM)) + { + DEBUG(4, ("skipping %s - system bit is set\n", finfo.name)); + shallitime=0; + } + else if (!tar_hidden && (finfo.mode & FILE_ATTRIBUTE_HIDDEN)) + { + DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name)); + shallitime=0; + } + else + { + DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s", + finfo.name, + (double)finfo.size, + lname)); - /* write a tar header, don't bother with mode - just set to 100644 */ - writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype); + /* write a tar header, don't bother with mode - just set to 100644 */ + writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype); - while (nread < finfo.size && !close_done) { + while (nread < finfo.size && !close_done) { - DEBUG(3,("nread=%.0f\n",(double)nread)); + DEBUG(3,("nread=%.0f\n",(double)nread)); - datalen = cli_read(cli, fnum, data, nread, read_size); + datalen = cli_read(cli->tree, fnum, data, nread, read_size); - if (datalen == -1) { - DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli))); - break; - } + if (datalen == -1) { + DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli->tree))); + break; + } - nread += datalen; - - /* if file size has increased since we made file size query, truncate - read so tar header for this file will be correct. - */ - - if (nread > finfo.size) { - datalen -= nread - finfo.size; - DEBUG(0,("File size change - truncating %s to %.0f bytes\n", - finfo.name, (double)finfo.size)); - } - - /* add received bits of file to buffer - dotarbuf will - * write out in 512 byte intervals */ - - if (dotarbuf(tarhandle,data,datalen) != datalen) { - DEBUG(0,("Error writing to tar file - %s\n", strerror(errno))); - break; - } + nread += datalen; + + /* if file size has increased since we made file size query, truncate + read so tar header for this file will be correct. + */ + + if (nread > finfo.size) { + datalen -= nread - finfo.size; + DEBUG(0,("File size change - truncating %s to %.0f bytes\n", finfo.name, (double)finfo.size)); + } + + /* add received bits of file to buffer - dotarbuf will + * write out in 512 byte intervals */ + if (dotarbuf(tarhandle,data,datalen) != datalen) { + DEBUG(0,("Error writing to tar file - %s\n", strerror(errno))); + break; + } - if (datalen == 0) { - DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname)); - break; - } - - datalen=0; - } - - /* pad tar file with zero's if we couldn't get entire file */ - if (nread < finfo.size) { - DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", - (double)finfo.size, (int)nread)); - if (padit(data, sizeof(data), finfo.size - nread)) - DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); - } - - /* round tar file to nearest block */ - if (finfo.size % TBLOCK) - dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); + if (datalen == 0) { + DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname)); + break; + } + + datalen=0; + } + + /* pad tar file with zero's if we couldn't get entire file */ + if (nread < finfo.size) { + DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", (double)finfo.size, (int)nread)); + if (padit(data, sizeof(data), finfo.size - nread)) + DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); + } + + /* round tar file to nearest block */ + if (finfo.size % TBLOCK) + dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK)); - ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); - ntarf++; - } + ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); + ntarf++; + } - cli_close(cli, fnum); + cli_close(cli->tree, fnum); - if (shallitime) { - struct timeval tp_end; - int this_time; + if (shallitime) + { + struct timeval tp_end; + int this_time; - /* if shallitime is true then we didn't skip */ - if (tar_reset && !dry_run) - (void) do_setrattr(finfo.name, aARCH, ATTRRESET); + /* if shallitime is true then we didn't skip */ + if (tar_reset && !dry_run) + (void) do_setrattr(finfo.name, FILE_ATTRIBUTE_ARCHIVE, ATTRRESET); - GetTimeOfDay(&tp_end); - this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000; - get_total_time_ms += this_time; - get_total_size += finfo.size; - - if (tar_noisy) { - DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n", - (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)), - finfo.name)); - } - - /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */ - DEBUG(3,("(%g kb/s) (average %g kb/s)\n", - finfo.size / MAX(0.001, (1.024*this_time)), - get_total_size / MAX(0.001, (1.024*get_total_time_ms)))); + GetTimeOfDay(&tp_end); + this_time = + (tp_end.tv_sec - tp_start.tv_sec)*1000 + + (tp_end.tv_usec - tp_start.tv_usec)/1000; + get_total_time_ms += this_time; + get_total_size += finfo.size; + + if (tar_noisy) + { + DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n", + (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)), + finfo.name)); } + + /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */ + DEBUG(3,("(%g kb/s) (average %g kb/s)\n", + finfo.size / MAX(0.001, (1.024*this_time)), + get_total_size / MAX(0.001, (1.024*get_total_time_ms)))); + } } /**************************************************************************** Append single file to tar file (or not) ***************************************************************************/ - static void do_tar(file_info *finfo) { - pstring rname; + pstring rname; - if (strequal(finfo->name,"..") || strequal(finfo->name,".")) - return; + if (strequal(finfo->name,"..") || strequal(finfo->name,".")) + return; - /* Is it on the exclude list ? */ - if (!tar_excl && clipn) { - pstring exclaim; + /* Is it on the exclude list ? */ + if (!tar_excl && clipn) { + pstring exclaim; - DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir))); + DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir))); - pstrcpy(exclaim, cur_dir); - *(exclaim+strlen(exclaim)-1)='\0'; + safe_strcpy(exclaim, cur_dir, sizeof(pstring)); + *(exclaim+strlen(exclaim)-1)='\0'; - pstrcat(exclaim, "\\"); - pstrcat(exclaim, finfo->name); + safe_strcat(exclaim, "\\", sizeof(pstring)); + safe_strcat(exclaim, finfo->name, sizeof(exclaim)); - DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); + DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); - if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) || + if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) || #ifdef HAVE_REGEX_H - (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) { + (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) { #else - (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) { + (tar_re_search && mask_match(cli, exclaim, cliplist[0], True))) { #endif - DEBUG(3,("Skipping file %s\n", exclaim)); - return; - } - } - - if (finfo->mode & aDIR) { - pstring saved_curdir; - pstring mtar_mask; - - pstrcpy(saved_curdir, cur_dir); - - DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, \ -strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", - (int)sizeof(cur_dir), (int)strlen(cur_dir), - (int)strlen(finfo->name), finfo->name, cur_dir)); - - pstrcat(cur_dir,finfo->name); - pstrcat(cur_dir,"\\"); - - DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir)); - - /* write a tar directory, don't bother with mode - just set it to - * 40755 */ - writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5'); - if (tar_noisy) { - DEBUG(0,(" directory %s\n", cur_dir)); - } - ntarf++; /* Make sure we have a file on there */ - pstrcpy(mtar_mask,cur_dir); - pstrcat(mtar_mask,"*"); - DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask)); - do_list(mtar_mask, attribute, do_tar, False, True); - pstrcpy(cur_dir,saved_curdir); - } else { - pstrcpy(rname,cur_dir); - pstrcat(rname,finfo->name); - do_atar(rname,finfo->name,finfo); - } + DEBUG(3,("Skipping file %s\n", exclaim)); + return; + } + } + + if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) + { + pstring saved_curdir; + pstring mtar_mask; + + safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir)); + + DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir)); + + safe_strcat(cur_dir,finfo->name, sizeof(cur_dir)); + safe_strcat(cur_dir,"\\", sizeof(cur_dir)); + + DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir)); + + /* write a tar directory, don't bother with mode - just set it to + * 40755 */ + writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5'); + if (tar_noisy) { + DEBUG(0,(" directory %s\n", cur_dir)); + } + ntarf++; /* Make sure we have a file on there */ + safe_strcpy(mtar_mask,cur_dir, sizeof(pstring)); + safe_strcat(mtar_mask,"*", sizeof(pstring)); + DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask)); + do_list(mtar_mask, attribute, do_tar, False, True); + safe_strcpy(cur_dir,saved_curdir, sizeof(pstring)); + } + else + { + safe_strcpy(rname,cur_dir, sizeof(pstring)); + safe_strcat(rname,finfo->name, sizeof(pstring)); + do_atar(rname,finfo->name,finfo); + } } /**************************************************************************** Convert from UNIX to DOS file names ***************************************************************************/ - static void unfixtarname(char *tptr, char *fp, int l, BOOL first) { /* remove '.' from start of file name, convert from unix /'s to @@ -869,72 +879,79 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first) string_replace(tptr, '/', '\\'); } + /**************************************************************************** Move to the next block in the buffer, which may mean read in another set of blocks. FIXME, we should allow more than one block to be skipped. ****************************************************************************/ - static int next_block(char *ltarbuf, char **bufferp, int bufsiz) { - int bufread, total = 0; - - DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp)); - *bufferp += TBLOCK; - total = TBLOCK; - - if (*bufferp >= (ltarbuf + bufsiz)) { - - DEBUG(5, ("Reading more data into ltarbuf ...\n")); - - /* - * Bugfix from Bob Boehmer <boehmer@worldnet.att.net> - * Fixes bug where read can return short if coming from - * a pipe. - */ - - bufread = read(tarhandle, ltarbuf, bufsiz); - total = bufread; - - while (total < bufsiz) { - if (bufread < 0) { /* An error, return false */ - return (total > 0 ? -2 : bufread); - } - if (bufread == 0) { - if (total <= 0) { - return -2; - } - break; - } - bufread = read(tarhandle, <arbuf[total], bufsiz - total); - total += bufread; - } + int bufread, total = 0; - DEBUG(5, ("Total bytes read ... %i\n", total)); + DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp)); + *bufferp += TBLOCK; + total = TBLOCK; - *bufferp = ltarbuf; - } + if (*bufferp >= (ltarbuf + bufsiz)) { + + DEBUG(5, ("Reading more data into ltarbuf ...\n")); + + /* + * Bugfix from Bob Boehmer <boehmer@worldnet.att.net> + * Fixes bug where read can return short if coming from + * a pipe. + */ + + bufread = read(tarhandle, ltarbuf, bufsiz); + total = bufread; + + while (total < bufsiz) { + if (bufread < 0) { /* An error, return false */ + return (total > 0 ? -2 : bufread); + } + if (bufread == 0) { + if (total <= 0) { + return -2; + } + break; + } + bufread = read(tarhandle, <arbuf[total], bufsiz - total); + total += bufread; + } + + DEBUG(5, ("Total bytes read ... %i\n", total)); + + *bufferp = ltarbuf; + + } + + return(total); - return(total); } /* Skip a file, even if it includes a long file name? */ static int skip_file(int skipsize) { - int dsize = skipsize; + int dsize = skipsize; - DEBUG(5, ("Skiping file. Size = %i\n", skipsize)); + DEBUG(5, ("Skiping file. Size = %i\n", skipsize)); - /* FIXME, we should skip more than one block at a time */ + /* FIXME, we should skip more than one block at a time */ - while (dsize > 0) { - if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return(False); - } - dsize -= TBLOCK; - } + while (dsize > 0) { + + if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return(False); - return(True); + } + + dsize -= TBLOCK; + + } + + return(True); } /************************************************************* @@ -945,94 +962,102 @@ static int skip_file(int skipsize) static int get_file(file_info2 finfo) { - int fnum = -1, pos = 0, dsize = 0, bpos = 0; - SMB_BIG_UINT rsize = 0; + int fnum = -1, pos = 0, dsize = 0, rsize = 0, bpos = 0; - DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size)); + DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, (int)finfo.size)); - if (ensurepath(finfo.name) && - (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) { - DEBUG(0, ("abandoning restore\n")); - return(False); - } + if (ensurepath(finfo.name) && + (fnum=cli_open(cli->tree, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) { + DEBUG(0, ("abandoning restore\n")); + return(False); + } - /* read the blocks from the tar file and write to the remote file */ + /* read the blocks from the tar file and write to the remote file */ - rsize = finfo.size; /* This is how much to write */ + rsize = finfo.size; /* This is how much to write */ - while (rsize > 0) { + while (rsize > 0) { - /* We can only write up to the end of the buffer */ - dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */ - dsize = MIN(dsize, rsize); /* Should be only what is left */ - DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos)); + /* We can only write up to the end of the buffer */ - if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) { - DEBUG(0, ("Error writing remote file\n")); - return 0; - } + dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */ + dsize = MIN(dsize, rsize); /* Should be only what is left */ + DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos)); - rsize -= dsize; - pos += dsize; + if (cli_write(cli->tree, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) { + DEBUG(0, ("Error writing remote file\n")); + return 0; + } - /* Now figure out how much to move in the buffer */ + rsize -= dsize; + pos += dsize; - /* FIXME, we should skip more than one block at a time */ + /* Now figure out how much to move in the buffer */ - /* First, skip any initial part of the part written that is left over */ - /* from the end of the first TBLOCK */ + /* FIXME, we should skip more than one block at a time */ - if ((bpos) && ((bpos + dsize) >= TBLOCK)) { - dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */ - bpos = 0; + /* First, skip any initial part of the part written that is left over */ + /* from the end of the first TBLOCK */ - if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */ - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return False; - } - } + if ((bpos) && ((bpos + dsize) >= TBLOCK)) { - /* - * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>. - * If the file being extracted is an exact multiple of - * TBLOCK bytes then we don't want to extract the next - * block from the tarfile here, as it will be done in - * the caller of get_file(). - */ + dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */ + bpos = 0; - while (((rsize != 0) && (dsize >= TBLOCK)) || - ((rsize == 0) && (dsize > TBLOCK))) { + if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */ + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return False; - if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return False; - } + } - dsize -= TBLOCK; - } - bpos = dsize; - } + } - /* Now close the file ... */ + /* + * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>. + * If the file being extracted is an exact multiple of + * TBLOCK bytes then we don't want to extract the next + * block from the tarfile here, as it will be done in + * the caller of get_file(). + */ - if (!cli_close(cli, fnum)) { - DEBUG(0, ("Error closing remote file\n")); - return(False); - } + while (((rsize != 0) && (dsize >= TBLOCK)) || + ((rsize == 0) && (dsize > TBLOCK))) { - /* Now we update the creation date ... */ - DEBUG(5, ("Updating creation date on %s\n", finfo.name)); + if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return False; + } - if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) { - if (tar_real_noisy) { - DEBUG(0, ("Could not set time on file: %s\n", finfo.name)); - /*return(False); */ /* Ignore, as Win95 does not allow changes */ - } - } + dsize -= TBLOCK; + } + + bpos = dsize; + + } + + /* Now close the file ... */ - ntarf++; - DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size)); - return(True); + if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) { + DEBUG(0, ("Error closing remote file\n")); + return(False); + } + + /* Now we update the creation date ... */ + + DEBUG(5, ("Updating creation date on %s\n", finfo.name)); + + if (NT_STATUS_IS_ERR(cli_setatr(cli->tree, finfo.name, finfo.mode, finfo.mtime))) { + if (tar_real_noisy) { + DEBUG(0, ("Could not set time on file: %s\n", finfo.name)); + /*return(False); */ /* Ignore, as Win95 does not allow changes */ + } + } + + ntarf++; + + DEBUG(0, ("restore tar file %s of size %d bytes\n", finfo.name, (int)finfo.size)); + + return(True); } /* Create a directory. We just ensure that the path exists and return as there @@ -1040,169 +1065,214 @@ static int get_file(file_info2 finfo) */ static int get_dir(file_info2 finfo) { - DEBUG(0, ("restore directory %s\n", finfo.name)); - if (!ensurepath(finfo.name)) { - DEBUG(0, ("Problems creating directory\n")); - return(False); - } - ntarf++; - return(True); -} + DEBUG(0, ("restore directory %s\n", finfo.name)); + + if (!ensurepath(finfo.name)) { + DEBUG(0, ("Problems creating directory\n")); + return(False); + + } + + ntarf++; + return(True); + +} /* Get a file with a long file name ... first file has file name, next file has the data. We only want the long file name, as the loop in do_tarput will deal with the rest. */ -static char *get_longfilename(file_info2 finfo) +static char * get_longfilename(file_info2 finfo) { - /* finfo.size here is the length of the filename as written by the "/./@LongLink" name - * header call. */ - int namesize = finfo.size + strlen(cur_dir) + 2; - char *longname = malloc(namesize); - int offset = 0, left = finfo.size; - BOOL first = True; - - DEBUG(5, ("Restoring a long file name: %s\n", finfo.name)); - DEBUG(5, ("Len = %.0f\n", (double)finfo.size)); - - if (longname == NULL) { - DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize)); - return(NULL); - } + int namesize = finfo.size + strlen(cur_dir) + 2; + char *longname = malloc(namesize); + int offset = 0, left = finfo.size; + BOOL first = True; - /* First, add cur_dir to the long file name */ + DEBUG(5, ("Restoring a long file name: %s\n", finfo.name)); + DEBUG(5, ("Len = %d\n", (int)finfo.size)); - if (strlen(cur_dir) > 0) { - strncpy(longname, cur_dir, namesize); - offset = strlen(cur_dir); - } + if (longname == NULL) { - /* Loop through the blocks picking up the name */ + DEBUG(0, ("could not allocate buffer of size %d for longname\n", + (int)(finfo.size + strlen(cur_dir) + 2))); + return(NULL); + } - while (left > 0) { - if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return(NULL); - } + /* First, add cur_dir to the long file name */ - unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--); - DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p)); + if (strlen(cur_dir) > 0) { + strncpy(longname, cur_dir, namesize); + offset = strlen(cur_dir); + } - offset += TBLOCK; - left -= TBLOCK; - } + /* Loop through the blocks picking up the name */ + + while (left > 0) { + + if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + return(NULL); + + } + + unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--); + DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p)); + + offset += TBLOCK; + left -= TBLOCK; + + } + + return(longname); - return(longname); } static void do_tarput(void) { - file_info2 finfo; - struct timeval tp_start; - char *longfilename = NULL, linkflag; - int skip = False; - - GetTimeOfDay(&tp_start); - DEBUG(5, ("RJS do_tarput called ...\n")); - - buffer_p = tarbuf + tbufsiz; /* init this to force first read */ - - /* Now read through those files ... */ - while (True) { - /* Get us to the next block, or the first block first time around */ - if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { - DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); - return; - } + file_info2 finfo; + struct timeval tp_start; + char *longfilename = NULL, linkflag; + int skip = False; - DEBUG(5, ("Reading the next header ...\n")); + GetTimeOfDay(&tp_start); - switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) { - case -2: /* Hmm, not good, but not fatal */ - DEBUG(0, ("Skipping %s...\n", finfo.name)); - if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) { - DEBUG(0, ("Short file, bailing out...\n")); - return; - } - break; + DEBUG(5, ("RJS do_tarput called ...\n")); - case -1: - DEBUG(0, ("abandoning restore, -1 from read tar header\n")); - return; + buffer_p = tarbuf + tbufsiz; /* init this to force first read */ - case 0: /* chksum is zero - looks like an EOF */ - DEBUG(0, ("tar: restored %d files and directories\n", ntarf)); - return; /* Hmmm, bad here ... */ + /* Now read through those files ... */ - default: - /* No action */ - break; - } + while (True) { - /* Now, do we have a long file name? */ - if (longfilename != NULL) { - SAFE_FREE(finfo.name); /* Free the space already allocated */ - finfo.name = longfilename; - longfilename = NULL; - } + /* Get us to the next block, or the first block first time around */ + + if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { + + DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); + + return; + + } + + DEBUG(5, ("Reading the next header ...\n")); + + switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) { + + case -2: /* Hmm, not good, but not fatal */ + DEBUG(0, ("Skipping %s...\n", finfo.name)); + if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && + !skip_file(finfo.size)) { + + DEBUG(0, ("Short file, bailing out...\n")); + return; + + } + + break; + + case -1: + DEBUG(0, ("abandoning restore, -1 from read tar header\n")); + return; + + case 0: /* chksum is zero - looks like an EOF */ + DEBUG(0, ("tar: restored %d files and directories\n", ntarf)); + return; /* Hmmm, bad here ... */ + + default: + /* No action */ + + break; + + } + + /* Now, do we have a long file name? */ + + if (longfilename != NULL) { + + SAFE_FREE(finfo.name); /* Free the space already allocated */ + finfo.name = longfilename; + longfilename = NULL; + + } + + /* Well, now we have a header, process the file ... */ - /* Well, now we have a header, process the file ... */ - /* Should we skip the file? We have the long name as well here */ - skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) || + /* Should we skip the file? We have the long name as well here */ + + skip = clipn && + ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) #ifdef HAVE_REGEX_H - (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0))); + || (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0))); #else - (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True))); + || (tar_re_search && mask_match(cli, finfo.name, cliplist[0], True))); #endif - DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name)); - if (skip) { - skip_file(finfo.size); - continue; - } + DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name)); + + if (skip) { + + skip_file(finfo.size); + continue; + + } + + /* We only get this far if we should process the file */ + linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag; + + switch (linkflag) { + + case '0': /* Should use symbolic names--FIXME */ + + /* + * Skip to the next block first, so we can get the file, FIXME, should + * be in get_file ... + * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net> + * Fixes bug where file size in tarfile is zero. + */ + + if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) { + DEBUG(0, ("Short file, bailing out...\n")); + return; + } + if (!get_file(finfo)) { + DEBUG(0, ("Abandoning restore\n")); + return; + + } + break; + + case '5': + if (!get_dir(finfo)) { + DEBUG(0, ("Abandoning restore \n")); + return; + } + break; + + case 'L': + longfilename = get_longfilename(finfo); + if (!longfilename) { + DEBUG(0, ("abandoning restore\n")); + return; + + } + DEBUG(5, ("Long file name: %s\n", longfilename)); + break; + + default: + skip_file(finfo.size); /* Don't handle these yet */ + break; + + } + + } + - /* We only get this far if we should process the file */ - linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag; - switch (linkflag) { - case '0': /* Should use symbolic names--FIXME */ - /* - * Skip to the next block first, so we can get the file, FIXME, should - * be in get_file ... - * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net> - * Fixes bug where file size in tarfile is zero. - */ - if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) { - DEBUG(0, ("Short file, bailing out...\n")); - return; - } - if (!get_file(finfo)) { - DEBUG(0, ("Abandoning restore\n")); - return; - } - break; - case '5': - if (!get_dir(finfo)) { - DEBUG(0, ("Abandoning restore \n")); - return; - } - break; - case 'L': - longfilename = get_longfilename(finfo); - if (!longfilename) { - DEBUG(0, ("abandoning restore\n")); - return; - } - DEBUG(5, ("Long file name: %s\n", longfilename)); - break; - - default: - skip_file(finfo.size); /* Don't handle these yet */ - break; - } - } } + /* * samba interactive commands */ @@ -1210,598 +1280,577 @@ static void do_tarput(void) /**************************************************************************** Blocksize command ***************************************************************************/ - int cmd_block(void) { - fstring buf; - int block; - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { - DEBUG(0, ("blocksize <n>\n")); - return 1; - } - - block=atoi(buf); - if (block < 0 || block > 65535) { - DEBUG(0, ("blocksize out of range")); - return 1; - } - - blocksize=block; - DEBUG(2,("blocksize is now %d\n", blocksize)); - - return 0; + fstring buf; + int block; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) + { + DEBUG(0, ("blocksize <n>\n")); + return 1; + } + + block=atoi(buf); + if (block < 0 || block > 65535) + { + DEBUG(0, ("blocksize out of range")); + return 1; + } + + blocksize=block; + DEBUG(2,("blocksize is now %d\n", blocksize)); + + return 0; } /**************************************************************************** command to set incremental / reset mode ***************************************************************************/ - int cmd_tarmode(void) { - fstring buf; - - while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { - if (strequal(buf, "full")) - tar_inc=False; - else if (strequal(buf, "inc")) - tar_inc=True; - else if (strequal(buf, "reset")) - tar_reset=True; - else if (strequal(buf, "noreset")) - tar_reset=False; - else if (strequal(buf, "system")) - tar_system=True; - else if (strequal(buf, "nosystem")) - tar_system=False; - else if (strequal(buf, "hidden")) - tar_hidden=True; - else if (strequal(buf, "nohidden")) - tar_hidden=False; - else if (strequal(buf, "verbose") || strequal(buf, "noquiet")) - tar_noisy=True; - else if (strequal(buf, "quiet") || strequal(buf, "noverbose")) - tar_noisy=False; - else - DEBUG(0, ("tarmode: unrecognised option %s\n", buf)); - } - - DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n", - tar_inc ? "incremental" : "full", - tar_system ? "system" : "nosystem", - tar_hidden ? "hidden" : "nohidden", - tar_reset ? "reset" : "noreset", - tar_noisy ? "verbose" : "quiet")); - return 0; + fstring buf; + + while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { + if (strequal(buf, "full")) + tar_inc=False; + else if (strequal(buf, "inc")) + tar_inc=True; + else if (strequal(buf, "reset")) + tar_reset=True; + else if (strequal(buf, "noreset")) + tar_reset=False; + else if (strequal(buf, "system")) + tar_system=True; + else if (strequal(buf, "nosystem")) + tar_system=False; + else if (strequal(buf, "hidden")) + tar_hidden=True; + else if (strequal(buf, "nohidden")) + tar_hidden=False; + else if (strequal(buf, "verbose") || strequal(buf, "noquiet")) + tar_noisy=True; + else if (strequal(buf, "quiet") || strequal(buf, "noverbose")) + tar_noisy=False; + else DEBUG(0, ("tarmode: unrecognised option %s\n", buf)); + } + + DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n", + tar_inc ? "incremental" : "full", + tar_system ? "system" : "nosystem", + tar_hidden ? "hidden" : "nohidden", + tar_reset ? "reset" : "noreset", + tar_noisy ? "verbose" : "quiet")); + + return 0; } /**************************************************************************** Feeble attrib command ***************************************************************************/ - int cmd_setmode(void) { - char *q; - fstring buf; - pstring fname; - uint16 attra[2]; - int direct=1; - - attra[0] = attra[1] = 0; - - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { - DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); - return 1; - } + char *q; + fstring buf; + pstring fname; + uint16 attra[2]; + int direct=1; + + attra[0] = attra[1] = 0; + + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) + { + DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); + return 1; + } + + safe_strcpy(fname, cur_dir, sizeof(pstring)); + safe_strcat(fname, buf, sizeof(pstring)); + + while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { + q=buf; + + while(*q) + switch (*q++) { + case '+': direct=1; + break; + case '-': direct=0; + break; + case 'r': attra[direct]|=FILE_ATTRIBUTE_READONLY; + break; + case 'h': attra[direct]|=FILE_ATTRIBUTE_HIDDEN; + break; + case 's': attra[direct]|=FILE_ATTRIBUTE_SYSTEM; + break; + case 'a': attra[direct]|=FILE_ATTRIBUTE_ARCHIVE; + break; + default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n")); + return 1; + } + } - pstrcpy(fname, cur_dir); - pstrcat(fname, buf); - - while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { - q=buf; - - while(*q) { - switch (*q++) { - case '+': - direct=1; - break; - case '-': - direct=0; - break; - case 'r': - attra[direct]|=aRONLY; - break; - case 'h': - attra[direct]|=aHIDDEN; - break; - case 's': - attra[direct]|=aSYSTEM; - break; - case 'a': - attra[direct]|=aARCH; - break; - default: - DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n")); - return 1; - } - } - } + if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) + { + DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); + return 1; + } - if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) { - DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); - return 1; - } + DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET])); + do_setrattr(fname, attra[ATTRSET], ATTRSET); + do_setrattr(fname, attra[ATTRRESET], ATTRRESET); - DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET])); - do_setrattr(fname, attra[ATTRSET], ATTRSET); - do_setrattr(fname, attra[ATTRRESET], ATTRRESET); - return 0; + return 0; } /**************************************************************************** Principal command for creating / extracting ***************************************************************************/ - int cmd_tar(void) { - fstring buf; - char **argl; - int argcl; + fstring buf; + char **argl; + int argcl; - if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { - DEBUG(0,("tar <c|x>[IXbgan] <filename>\n")); - return 1; - } + if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) + { + DEBUG(0,("tar <c|x>[IXbgan] <filename>\n")); + return 1; + } - argl=toktocliplist(&argcl, NULL); - if (!tar_parseargs(argcl, argl, buf, 0)) - return 1; + argl=toktocliplist(&argcl, NULL); + if (!tar_parseargs(argcl, argl, buf, 0)) + return 1; - process_tar(); - SAFE_FREE(argl); - return 0; + process_tar(); + + SAFE_FREE(argl); + + return 0; } /**************************************************************************** Command line (option) version ***************************************************************************/ - int process_tar(void) { - initarbuf(); - switch(tar_type) { - case 'x': + initarbuf(); + switch(tar_type) { + case 'x': #if 0 - do_tarput2(); + do_tarput2(); #else - do_tarput(); + do_tarput(); #endif - SAFE_FREE(tarbuf); - close(tarhandle); - break; - case 'r': - case 'c': - if (clipn && tar_excl) { - int i; - pstring tarmac; - - for (i=0; i<clipn; i++) { - DEBUG(5,("arg %d = %s\n", i, cliplist[i])); - - if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') { - *(cliplist[i]+strlen(cliplist[i])-1)='\0'; - } + SAFE_FREE(tarbuf); + close(tarhandle); + break; + case 'r': + case 'c': + if (clipn && tar_excl) { + int i; + pstring tarmac; + + for (i=0; i<clipn; i++) { + DEBUG(5,("arg %d = %s\n", i, cliplist[i])); + + if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') { + *(cliplist[i]+strlen(cliplist[i])-1)='\0'; + } - if (strrchr_m(cliplist[i], '\\')) { - pstring saved_dir; + if (strrchr_m(cliplist[i], '\\')) { + pstring saved_dir; - pstrcpy(saved_dir, cur_dir); + safe_strcpy(saved_dir, cur_dir, sizeof(pstring)); - if (*cliplist[i]=='\\') { - pstrcpy(tarmac, cliplist[i]); - } else { - pstrcpy(tarmac, cur_dir); - pstrcat(tarmac, cliplist[i]); - } - pstrcpy(cur_dir, tarmac); - *(strrchr_m(cur_dir, '\\')+1)='\0'; - - DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); - do_list(tarmac,attribute,do_tar, False, True); - pstrcpy(cur_dir,saved_dir); - } else { - pstrcpy(tarmac, cur_dir); - pstrcat(tarmac, cliplist[i]); - DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); - do_list(tarmac,attribute,do_tar, False, True); - } - } - } else { - pstring mask; - pstrcpy(mask,cur_dir); - DEBUG(5, ("process_tar, do_list with mask: %s\n", mask)); - pstrcat(mask,"\\*"); - do_list(mask,attribute,do_tar,False, True); - } + if (*cliplist[i]=='\\') { + safe_strcpy(tarmac, cliplist[i], sizeof(pstring)); + } else { + safe_strcpy(tarmac, cur_dir, sizeof(pstring)); + safe_strcat(tarmac, cliplist[i], sizeof(pstring)); + } + safe_strcpy(cur_dir, tarmac, sizeof(pstring)); + *(strrchr_m(cur_dir, '\\')+1)='\0'; + + DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); + do_list(tarmac,attribute,do_tar, False, True); + safe_strcpy(cur_dir,saved_dir, sizeof(pstring)); + } else { + safe_strcpy(tarmac, cur_dir, sizeof(pstring)); + safe_strcat(tarmac, cliplist[i], sizeof(pstring)); + DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac)); + do_list(tarmac,attribute,do_tar, False, True); + } + } + } else { + pstring mask; + safe_strcpy(mask,cur_dir, sizeof(pstring)); + DEBUG(5, ("process_tar, do_list with mask: %s\n", mask)); + safe_strcat(mask,"\\*", sizeof(pstring)); + do_list(mask,attribute,do_tar,False, True); + } - if (ntarf) - dotareof(tarhandle); - close(tarhandle); - SAFE_FREE(tarbuf); + if (ntarf) dotareof(tarhandle); + close(tarhandle); + SAFE_FREE(tarbuf); - DEBUG(0, ("tar: dumped %d files and directories\n", ntarf)); - DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf)); - break; - } - - if (must_free_cliplist) { - int i; - for (i = 0; i < clipn; ++i) { - SAFE_FREE(cliplist[i]); - } - SAFE_FREE(cliplist); - cliplist = NULL; - clipn = 0; - must_free_cliplist = False; - } - return(0); + DEBUG(0, ("tar: dumped %d files and directories\n", ntarf)); + DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf)); + break; + } + + if (must_free_cliplist) { + int i; + for (i = 0; i < clipn; ++i) { + SAFE_FREE(cliplist[i]); + } + SAFE_FREE(cliplist); + cliplist = NULL; + clipn = 0; + must_free_cliplist = False; + } + + return(0); } /**************************************************************************** Find a token (filename) in a clip list ***************************************************************************/ - static int clipfind(char **aret, int ret, char *tok) { - if (aret==NULL) - return 0; + if (aret==NULL) return 0; - /* ignore leading slashes or dots in token */ - while(strchr_m("/\\.", *tok)) - tok++; + /* ignore leading slashes or dots in token */ + while(strchr_m("/\\.", *tok)) tok++; - while(ret--) { - char *pkey=*aret++; + while(ret--) { + char *pkey=*aret++; - /* ignore leading slashes or dots in list */ - while(strchr_m("/\\.", *pkey)) - pkey++; + /* ignore leading slashes or dots in list */ + while(strchr_m("/\\.", *pkey)) pkey++; - if (!strslashcmp(pkey, tok)) - return 1; - } - return 0; + if (!strslashcmp(pkey, tok)) return 1; + } + + return 0; } /**************************************************************************** Read list of files to include from the file and initialize cliplist accordingly. ***************************************************************************/ - static int read_inclusion_file(char *filename) { - XFILE *inclusion = NULL; - char buf[PATH_MAX + 1]; - char *inclusion_buffer = NULL; - int inclusion_buffer_size = 0; - int inclusion_buffer_sofar = 0; - char *p; - char *tmpstr; - int i; - int error = 0; - - clipn = 0; - buf[PATH_MAX] = '\0'; /* guarantee null-termination */ - if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) { - /* XXX It would be better to include a reason for failure, but without - * autoconf, it's hard to use strerror, sys_errlist, etc. - */ - DEBUG(0,("Unable to open inclusion file %s\n", filename)); - return 0; - } - - while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) { - if (inclusion_buffer == NULL) { - inclusion_buffer_size = 1024; - if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) { - DEBUG(0,("failure allocating buffer to read inclusion file\n")); - error = 1; - break; - } - } + XFILE *inclusion = NULL; + char buf[MAXPATHLEN + 1]; + char *inclusion_buffer = NULL; + int inclusion_buffer_size = 0; + int inclusion_buffer_sofar = 0; + char *p; + char *tmpstr; + int i; + int error = 0; + + clipn = 0; + buf[MAXPATHLEN] = '\0'; /* guarantee null-termination */ + if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) { + /* XXX It would be better to include a reason for failure, but without + * autoconf, it's hard to use strerror, sys_errlist, etc. + */ + DEBUG(0,("Unable to open inclusion file %s\n", filename)); + return 0; + } + + while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) { + if (inclusion_buffer == NULL) { + inclusion_buffer_size = 1024; + if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) { + DEBUG(0,("failure allocating buffer to read inclusion file\n")); + error = 1; + break; + } + } - if (buf[strlen(buf)-1] == '\n') { - buf[strlen(buf)-1] = '\0'; - } + if (buf[strlen(buf)-1] == '\n') { + buf[strlen(buf)-1] = '\0'; + } - if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) { - char *ib; - inclusion_buffer_size *= 2; - ib = Realloc(inclusion_buffer,inclusion_buffer_size); - if (! ib) { - DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n", - inclusion_buffer_size)); - error = 1; - break; - } else { - inclusion_buffer = ib; - } - } + if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) { + char *ib; + inclusion_buffer_size *= 2; + ib = Realloc(inclusion_buffer,inclusion_buffer_size); + if (! ib) { + DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n", + inclusion_buffer_size)); + error = 1; + break; + } + else inclusion_buffer = ib; + } - safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar); - inclusion_buffer_sofar += strlen(buf) + 1; - clipn++; - } - x_fclose(inclusion); - - if (! error) { - /* Allocate an array of clipn + 1 char*'s for cliplist */ - cliplist = malloc((clipn + 1) * sizeof(char *)); - if (cliplist == NULL) { - DEBUG(0,("failure allocating memory for cliplist\n")); - error = 1; - } else { - cliplist[clipn] = NULL; - p = inclusion_buffer; - for (i = 0; (! error) && (i < clipn); i++) { - /* set current item to NULL so array will be null-terminated even if - * malloc fails below. */ - cliplist[i] = NULL; - if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) { - DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i)); - error = 1; - } else { - unfixtarname(tmpstr, p, strlen(p) + 1, True); - cliplist[i] = tmpstr; - if ((p = strchr_m(p, '\000')) == NULL) { - DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n")); - abort(); - } - } - ++p; - } - must_free_cliplist = True; - } - } - - SAFE_FREE(inclusion_buffer); - if (error) { - if (cliplist) { - char **pp; - /* We know cliplist is always null-terminated */ - for (pp = cliplist; *pp; ++pp) { - SAFE_FREE(*pp); - } - SAFE_FREE(cliplist); - cliplist = NULL; - must_free_cliplist = False; - } - return 0; + safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar); + inclusion_buffer_sofar += strlen(buf) + 1; + clipn++; + } + x_fclose(inclusion); + + if (! error) { + /* Allocate an array of clipn + 1 char*'s for cliplist */ + cliplist = malloc((clipn + 1) * sizeof(char *)); + if (cliplist == NULL) { + DEBUG(0,("failure allocating memory for cliplist\n")); + error = 1; + } else { + cliplist[clipn] = NULL; + p = inclusion_buffer; + for (i = 0; (! error) && (i < clipn); i++) { + /* set current item to NULL so array will be null-terminated even if + * malloc fails below. */ + cliplist[i] = NULL; + if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) { + DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i)); + error = 1; + } else { + unfixtarname(tmpstr, p, strlen(p) + 1, True); + cliplist[i] = tmpstr; + if ((p = strchr_m(p, '\000')) == NULL) { + DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n")); + abort(); + } } + ++p; + } + must_free_cliplist = True; + } + } + + SAFE_FREE(inclusion_buffer); + if (error) { + if (cliplist) { + char **pp; + /* We know cliplist is always null-terminated */ + for (pp = cliplist; *pp; ++pp) { + SAFE_FREE(*pp); + } + SAFE_FREE(cliplist); + cliplist = NULL; + must_free_cliplist = False; + } + return 0; + } - /* cliplist and its elements are freed at the end of process_tar. */ - return 1; + /* cliplist and its elements are freed at the end of process_tar. */ + return 1; } /**************************************************************************** Parse tar arguments. Sets tar_type, tar_excl, etc. ***************************************************************************/ - int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind) { - int newOptind = Optind; - char tar_clipfl='\0'; - - /* Reset back to defaults - could be from interactive version - * reset mode and archive mode left as they are though - */ - tar_type='\0'; - tar_excl=True; - dry_run=False; - - while (*Optarg) { - switch(*Optarg++) { - case 'c': - tar_type='c'; - break; - case 'x': - if (tar_type=='c') { - printf("Tar must be followed by only one of c or x.\n"); - return 0; - } - tar_type='x'; - break; - case 'b': - if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) { - DEBUG(0,("Option b must be followed by valid blocksize\n")); - return 0; - } else { - Optind++; - newOptind++; - } - break; - case 'g': - tar_inc=True; - break; - case 'N': - if (Optind>=argc) { - DEBUG(0,("Option N must be followed by valid file name\n")); - return 0; - } else { - SMB_STRUCT_STAT stbuf; - extern time_t newer_than; + char tar_clipfl='\0'; + + /* Reset back to defaults - could be from interactive version + * reset mode and archive mode left as they are though + */ + tar_type='\0'; + tar_excl=True; + dry_run=False; + + while (*Optarg) + switch(*Optarg++) { + case 'c': + tar_type='c'; + break; + case 'x': + if (tar_type=='c') { + printf("Tar must be followed by only one of c or x.\n"); + return 0; + } + tar_type='x'; + break; + case 'b': + if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) { + DEBUG(0,("Option b must be followed by valid blocksize\n")); + return 0; + } else { + Optind++; + } + break; + case 'g': + tar_inc=True; + break; + case 'N': + if (Optind>=argc) { + DEBUG(0,("Option N must be followed by valid file name\n")); + return 0; + } else { + SMB_STRUCT_STAT stbuf; + extern time_t newer_than; - if (sys_stat(argv[Optind], &stbuf) == 0) { - newer_than = stbuf.st_mtime; - DEBUG(1,("Getting files newer than %s", - asctime(LocalTime(&newer_than)))); - newOptind++; - Optind++; - } else { - DEBUG(0,("Error setting newer-than time\n")); - return 0; - } - } - break; - case 'a': - tar_reset=True; - break; - case 'q': - tar_noisy=False; - break; - case 'I': - if (tar_clipfl) { - DEBUG(0,("Only one of I,X,F must be specified\n")); - return 0; - } - tar_clipfl='I'; - break; - case 'X': - if (tar_clipfl) { - DEBUG(0,("Only one of I,X,F must be specified\n")); - return 0; - } - tar_clipfl='X'; - break; - case 'F': - if (tar_clipfl) { - DEBUG(0,("Only one of I,X,F must be specified\n")); - return 0; - } - tar_clipfl='F'; - break; - case 'r': - DEBUG(0, ("tar_re_search set\n")); - tar_re_search = True; - break; - case 'n': - if (tar_type == 'c') { - DEBUG(0, ("dry_run set\n")); - dry_run = True; - } else { - DEBUG(0, ("n is only meaningful when creating a tar-file\n")); - return 0; - } - break; - default: - DEBUG(0,("Unknown tar option\n")); - return 0; - } - } - - if (!tar_type) { - printf("Option T must be followed by one of c or x.\n"); - return 0; - } - - /* tar_excl is true if cliplist lists files to be included. - * Both 'I' and 'F' mean include. */ - tar_excl=tar_clipfl!='X'; - - if (tar_clipfl=='F') { - if (argc-Optind-1 != 1) { - DEBUG(0,("Option F must be followed by exactly one filename.\n")); - return 0; - } - newOptind++; - Optind++; - if (! read_inclusion_file(argv[Optind])) { - return 0; - } - } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */ - char *tmpstr; - char **tmplist; - int clipcount; - - cliplist=argv+Optind+1; - clipn=argc-Optind-1; - clipcount = clipn; - - if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) { - DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn)); - return 0; - } - - for (clipcount = 0; clipcount < clipn; clipcount++) { - - DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount])); - - if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) { - DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount)); - return 0; - } - - unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True); - tmplist[clipcount] = tmpstr; - DEBUG(5, ("Processed an item, %s\n", tmpstr)); - - DEBUG(5, ("Cliplist is: %s\n", cliplist[0])); - } - - cliplist = tmplist; - must_free_cliplist = True; - - newOptind += clipn; + if (sys_stat(argv[Optind], &stbuf) == 0) { + newer_than = stbuf.st_mtime; + DEBUG(1,("Getting files newer than %s", + asctime(LocalTime(&newer_than)))); + Optind++; + } else { + DEBUG(0,("Error setting newer-than time\n")); + return 0; } - - if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */ + } + break; + case 'a': + tar_reset=True; + break; + case 'q': + tar_noisy=False; + break; + case 'I': + if (tar_clipfl) { + DEBUG(0,("Only one of I,X,F must be specified\n")); + return 0; + } + tar_clipfl='I'; + break; + case 'X': + if (tar_clipfl) { + DEBUG(0,("Only one of I,X,F must be specified\n")); + return 0; + } + tar_clipfl='X'; + break; + case 'F': + if (tar_clipfl) { + DEBUG(0,("Only one of I,X,F must be specified\n")); + return 0; + } + tar_clipfl='F'; + break; + case 'r': + DEBUG(0, ("tar_re_search set\n")); + tar_re_search = True; + break; + case 'n': + if (tar_type == 'c') { + DEBUG(0, ("dry_run set\n")); + dry_run = True; + } else { + DEBUG(0, ("n is only meaningful when creating a tar-file\n")); + return 0; + } + break; + default: + DEBUG(0,("Unknown tar option\n")); + return 0; + } + + if (!tar_type) { + printf("Option T must be followed by one of c or x.\n"); + return 0; + } + + /* tar_excl is true if cliplist lists files to be included. + * Both 'I' and 'F' mean include. */ + tar_excl=tar_clipfl!='X'; + + if (tar_clipfl=='F') { + if (argc-Optind-1 != 1) { + DEBUG(0,("Option F must be followed by exactly one filename.\n")); + return 0; + } + if (! read_inclusion_file(argv[Optind+1])) { + return 0; + } + } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */ + char *tmpstr; + char **tmplist; + int clipcount; + + cliplist=argv+Optind+1; + clipn=argc-Optind-1; + clipcount = clipn; + + if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) { + DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", + clipn) + ); + return 0; + } + + for (clipcount = 0; clipcount < clipn; clipcount++) { + + DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount])); + + if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) { + DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", + clipcount) + ); + return 0; + } + unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True); + tmplist[clipcount] = tmpstr; + DEBUG(5, ("Processed an item, %s\n", tmpstr)); + + DEBUG(5, ("Cliplist is: %s\n", cliplist[0])); + } + cliplist = tmplist; + must_free_cliplist = True; + } + + if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */ #ifdef HAVE_REGEX_H - int errcode; + int errcode; - if ((preg = (regex_t *)malloc(65536)) == NULL) { + if ((preg = (regex_t *)malloc(65536)) == NULL) { - DEBUG(0, ("Could not allocate buffer for regular expression search\n")); - return; - } + DEBUG(0, ("Could not allocate buffer for regular expression search\n")); + return; - if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) { - char errstr[1024]; - size_t errlen; + } - errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1); - DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr)); - return; - } -#endif + if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) { + char errstr[1024]; + size_t errlen; - clipn=argc-Optind-1; - cliplist=argv+Optind+1; - newOptind += clipn; - } + errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1); + + DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr)); + return; - if (Optind>=argc || !strcmp(argv[Optind], "-")) { - /* Sets tar handle to either 0 or 1, as appropriate */ - tarhandle=(tar_type=='c'); - /* - * Make sure that dbf points to stderr if we are using stdout for - * tar output - */ - if (tarhandle == 1) { - dbf = x_stderr; - } - if (!argv[Optind]) { - DEBUG(0,("Must specify tar filename\n")); - return 0; - } - if (!strcmp(argv[Optind], "-")) { - newOptind++; - } + } +#endif - } else { - if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) { - if (!dry_run) { - DEBUG(0,("Output is /dev/null, assuming dry_run\n")); - dry_run = True; - } - tarhandle=-1; - } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1) - || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) { - DEBUG(0,("Error opening local file %s - %s\n", argv[Optind], strerror(errno))); - return(0); - } - newOptind++; + clipn=argc-Optind-1; + cliplist=argv+Optind+1; + + } + + if (Optind>=argc || !strcmp(argv[Optind], "-")) { + /* Sets tar handle to either 0 or 1, as appropriate */ + tarhandle=(tar_type=='c'); + /* + * Make sure that dbf points to stderr if we are using stdout for + * tar output + */ + if (tarhandle == 1) + setup_logging("clitar", DEBUG_STDERR); + } else { + if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) + { + if (!dry_run) { + DEBUG(0,("Output is /dev/null, assuming dry_run\n")); + dry_run = True; } + tarhandle=-1; + } else + if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1) + || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) + { + DEBUG(0,("Error opening local file %s - %s\n", + argv[Optind], strerror(errno))); + return(0); + } + } - return newOptind; + return 1; } diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c index 8c23cc22123..7167859d7b2 100755 --- a/source/client/mount.cifs.c +++ b/source/client/mount.cifs.c @@ -1,27 +1,6 @@ -/* - Mount helper utility for Linux CIFS VFS (virtual filesystem) client - Copyright (C) 2003 Steve French (sfrench@us.ibm.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _GNU_SOURCE #define _GNU_SOURCE -#endif #include <stdlib.h> -#include <stdio.h> #include <unistd.h> #include <pwd.h> #include <sys/types.h> @@ -35,14 +14,10 @@ #include <netdb.h> #include <string.h> #include <mntent.h> -#include <fcntl.h> -#define MOUNT_CIFS_VERSION_MAJOR "1" -#define MOUNT_CIFS_VERSION_MINOR "0" +#define MOUNT_CIFS_VERSION "1" -#ifndef MOUNT_CIFS_VENDOR_SUFFIX -#define MOUNT_CIFS_VENDOR_SUFFIX "" -#endif +extern char *getusername(void); char * thisprogram; int verboseflag = 0; @@ -57,29 +32,17 @@ static char * user_name = NULL; char * mountpassword = NULL; -/* BB finish BB - - cifs_umount - open nofollow - avoid symlink exposure? - get owner of dir see if matches self or if root - call system(umount argv) etc. - -BB end finish BB */ - -static void mount_cifs_usage(void) +void mount_cifs_usage() { - printf("\nUsage: %s <remotetarget> <dir> -o <options>\n", thisprogram); - printf("\nMount the remote target, specified as a UNC name,"); - printf(" to a local directory.\n"); - if(mountpassword) { - memset(mountpassword,0,64); - free(mountpassword); - } + printf("\nUsage: %s remotetarget dir\n", thisprogram); + printf("\nMount the remotetarget, specified as either a UNC name or "); + printf(" CIFS URL, to the local directory, dir.\n"); + exit(1); } /* caller frees username if necessary */ -static char * getusername(void) { +char * getusername() { char *username = NULL; struct passwd *password = getpwuid(getuid()); @@ -89,185 +52,25 @@ static char * getusername(void) { return username; } -char * parse_cifs_url(char * unc_name) +char * parse_cifs_url(unc_name) { printf("\ncifs url %s\n",unc_name); - return NULL; -} - -static int open_cred_file(char * file_name) -{ - char * line_buf; - char * temp_val; - FILE * fs; - int i, length; - fs = fopen(file_name,"r"); - if(fs == NULL) - return errno; - line_buf = malloc(4096); - if(line_buf == NULL) - return -ENOMEM; - - while(fgets(line_buf,4096,fs)) { - /* parse line from credential file */ - - /* eat leading white space */ - for(i=0;i<4096;i++) { - if(line_buf[i] == '\0') - break; - else if((line_buf[i] != ' ') && (line_buf[i] != '\t')) - break; - line_buf++; - } - - if (strncasecmp("username",line_buf,8) == 0) { - temp_val = strchr(line_buf + i,'='); - if(temp_val) { - /* go past equals sign */ - temp_val++; - length = strlen(temp_val); - if(length > 4086) { - printf("cifs.mount failed due to malformed username in credentials file"); - memset(line_buf,0,4096); - if(mountpassword) { - memset(mountpassword,0,64); - } - exit(1); - } else { - got_user = 1; - user_name = calloc(1 + length,1); - /* BB adding free of user_name string before exit, - not really necessary but would be cleaner */ - strncpy(user_name,temp_val, length); - } - } - } else if (strncasecmp("password",line_buf,8) == 0) { - temp_val = strchr(line_buf+i,'='); - if(temp_val) { - /* go past equals sign */ - temp_val++; - length = strlen(temp_val); - if(length > 64) { - printf("cifs.mount failed: password in credentials file too long\n"); - memset(line_buf,0, 4096); - if(mountpassword) { - memset(mountpassword,0,64); - } - exit(1); - } else { - if(mountpassword == NULL) { - mountpassword = calloc(65,1); - } - if(mountpassword) { - strncpy(mountpassword,temp_val,64); - got_password = 1; - } - } - } - } - } - fclose(fs); - if(line_buf) { - memset(line_buf,0,4096); - free(line_buf); - } - return 0; } -static int get_password_from_file(int file_descript, char * filename) -{ - int rc = 0; - int i; - char c; - - if(mountpassword == NULL) - mountpassword = calloc(65,1); - else - memset(mountpassword, 0, 64); - - if(filename != NULL) { - file_descript = open(filename, O_RDONLY); - if(file_descript < 0) { - printf("cifs.mount failed. %s attempting to open password file %s\n", - strerror(errno),filename); - exit(1); - } - } - /* else file already open and fd provided */ - - for(i=0;i<64;i++) { - rc = read(file_descript,&c,1); - if(rc < 0) { - printf("cifs.mount failed. Error %s reading password file\n",strerror(errno)); - memset(mountpassword,0,64); - if(filename != NULL) - close(file_descript); - exit(1); - } else if(rc == 0) { - if(mountpassword[0] == 0) { - if(verboseflag) - printf("\nWarning: null password used since cifs password file empty"); - } - break; - } else /* read valid character */ { - if((c == 0) || (c == '\n')) { - break; - } else - mountpassword[i] = c; - } - } - if((i == 64) && (verboseflag)) { - printf("\nWarning: password longer than 64 characters specified in cifs password file"); - } - got_password = 1; - if(filename != NULL) { - close(file_descript); - } - - return rc; -} - -static int parse_options(char * options) +int parse_options(char * options) { char * data; - char * percent_char = 0; char * value = 0; - char * next_keyword = 0; - int rc = 0; if (!options) return 1; - else - data = options; - - if(verboseflag) - printf("\n parsing options: %s", options); -/* while ((data = strsep(&options, ",")) != NULL) { */ - while(data != NULL) { - /* check if ends with trailing comma */ - if(*data == 0) - break; - - /* format is keyword=value,keyword2=value2,keyword3=value3 etc.) */ - /* data = next keyword */ - /* value = next value ie stuff after equal sign */ - - next_keyword = strchr(data,','); - - /* temporarily null terminate end of keyword=value pair */ - if(next_keyword) - *next_keyword = 0; - - /* if (!*data) - continue; */ - - /* temporarily null terminate keyword to make keyword and value distinct */ + while ((data = strsep(&options, ",")) != NULL) { + if (!*data) + continue; if ((value = strchr(data, '=')) != NULL) { - *value = '\0'; - value++; + *value++ = '\0'; } - if (strncmp(data, "user", 4) == 0) { if (!value || !*value) { printf("invalid or missing username\n"); @@ -275,142 +78,94 @@ static int parse_options(char * options) } if (strnlen(value, 260) < 260) { got_user=1; - percent_char = strchr(value,'%'); - if(percent_char) { - *percent_char = ','; - if(mountpassword == NULL) - mountpassword = calloc(65,1); - if(mountpassword) { - if(got_password) - printf("\ncifs.mount warning - password specified twice\n"); - got_password = 1; - percent_char++; - strncpy(mountpassword, percent_char,64); - /* remove password from username */ - while(*percent_char != 0) { - *percent_char = ','; - percent_char++; - } - } - } + /* BB add check for format user%pass */ + /* if(strchr(username%passw) got_password = 1) */ } else { printf("username too long\n"); return 1; } - } else if (strncmp(data, "pass", 4) == 0) { - if (!value || !*value) { - if(got_password) { - printf("\npassword specified twice, ignoring second\n"); - } else - got_password = 1; - } else if (strnlen(value, 17) < 17) { - if(got_password) - printf("\ncifs.mount warning - password specified twice\n"); + } else if (strncmp(data, "pass", 4) == 0) { + if (!value || !*value) { + if(got_password) { + printf("password specified twice, ignoring second\n"); + } else got_password = 1; - } else { - printf("password too long\n"); - return 1; - } - } else if (strncmp(data, "ip", 2) == 0) { - if (!value || !*value) { - printf("target ip address argument missing"); - } else if (strnlen(value, 35) < 35) { - got_ip = 1; - } else { - printf("ip address too long\n"); - return 1; - } - } else if ((strncmp(data, "unc", 3) == 0) + } else if (strnlen(value, 17) < 17) { + got_password = 1; + } else { + printf("password too long\n"); + return 1; + } + } else if (strncmp(data, "ip", 2) == 0) { + if (!value || !*value) { + printf("target ip address argument missing"); + } else if (strnlen(value, 35) < 35) { + got_ip = 1; + } else { + printf("ip address too long\n"); + return 1; + } + } else if ((strncmp(data, "unc", 3) == 0) || (strncmp(data, "target", 6) == 0) || (strncmp(data, "path", 4) == 0)) { - if (!value || !*value) { - printf("invalid path to network resource\n"); - return 1; /* needs_arg; */ - } else if(strnlen(value,5) < 5) { - printf("UNC name too short"); - } + if (!value || !*value) { + printf("invalid path to network resource\n"); + return 1; /* needs_arg; */ + } else if(strnlen(value,5) < 5) { + printf("UNC name too short"); + } - if (strnlen(value, 300) < 300) { - got_unc = 1; - if (strncmp(value, "//", 2) == 0) { - if(got_unc) - printf("unc name specified twice, ignoring second\n"); - else - got_unc = 1; - } else if (strncmp(value, "\\\\", 2) != 0) { - printf("UNC Path does not begin with // or \\\\ \n"); - return 1; - } else { - if(got_unc) - printf("unc name specified twice, ignoring second\n"); - else - got_unc = 1; - } - } else { - printf("CIFS: UNC name too long\n"); + if (strnlen(value, 300) < 300) { + got_unc = 1; + if (strncmp(value, "//", 2) == 0) { + if(got_unc) + printf("unc name specified twice, ignoring second\n"); + else + got_unc = 1; + } else if (strncmp(value, "\\\\", 2) != 0) { + printf("UNC Path does not begin with // or \\\\ \n"); return 1; - } - } else if ((strncmp(data, "domain", 3) == 0) - || (strncmp(data, "workgroup", 5) == 0)) { - if (!value || !*value) { - printf("CIFS: invalid domain name\n"); - return 1; /* needs_arg; */ - } - if (strnlen(value, 65) < 65) { - got_domain = 1; } else { - printf("domain name too long\n"); - return 1; - } - } else if (strncmp(data, "cred", 4) == 0) { - if (value && *value) { - rc = open_cred_file(value); - if(rc) { - printf("error %d opening credential file %s",rc, value); - return 1; - } - } else { - printf("invalid credential file name specified\n"); - return 1; + if(got_unc) + printf("unc name specified twice, ignoring second\n"); + else + got_unc = 1; } - } else if (strncmp(data, "uid", 3) == 0) { - if (value && *value) { - got_uid = 1; - } - } else if (strncmp(data, "gid", 3) == 0) { - if (value && *value) { - got_gid = 1; - } - /* fmask and dmask synonyms for people used to smbfs syntax */ - } else if (strcmp(data, "file_mode") == 0 || strcmp(data, "fmask")==0) { - if (!value || !*value) { - printf ("Option '%s' requires a numerical argument\n", data); - return 1; - } - - if (value[0] != '0') { - printf ("WARNING: '%s' not expressed in octal.\n", data); - } - - if (strcmp (data, "fmask") == 0) { - printf ("WARNING: CIFS mount option 'fmask' is deprecated. Use 'file_mode' instead.\n"); - data = "file_mode"; - } - } else if (strcmp(data, "dir_mode") == 0 || strcmp(data, "dmask")==0) { - if (!value || !*value) { - printf ("Option '%s' requires a numerical argument\n", data); - return 1; - } - - if (value[0] != '0') { - printf ("WARNING: '%s' not expressed in octal.\n", data); - } - - if (strcmp (data, "dmask") == 0) { - printf ("WARNING: CIFS mount option 'dmask' is deprecated. Use 'dir_mode' instead.\n"); - data = "dir_mode"; - } - } /* else if (strnicmp(data, "port", 4) == 0) { + } else { + printf("CIFS: UNC name too long\n"); + return 1; + } + } else if ((strncmp(data, "domain", 3) == 0) + || (strncmp(data, "workgroup", 5) == 0)) { + if (!value || !*value) { + printf("CIFS: invalid domain name\n"); + return 1; /* needs_arg; */ + } + if (strnlen(value, 65) < 65) { + got_domain = 1; + } else { + printf("domain name too long\n"); + return 1; + } + } else if (strncmp(data, "uid", 3) == 0) { + if (value && *value) { + got_uid = 1; + } + } else if (strncmp(data, "gid", 3) == 0) { + if (value && *value) { + got_gid = 1; + } + } /* else if (strnicmp(data, "file_mode", 4) == 0) { + if (value && *value) { + vol->file_mode = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "dir_mode", 3) == 0) { + if (value && *value) { + vol->dir_mode = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "port", 4) == 0) { if (value && *value) { vol->port = simple_strtoul(value, &value, 0); @@ -431,22 +186,6 @@ static int parse_options(char * options) } else printf("CIFS: Unknown mount option %s\n",data); */ - - /* move to next option */ - data = next_keyword+1; - - /* put overwritten equals sign back */ - if(value) { - value--; - *value = '='; - } - - /* put previous overwritten comma back */ - if(next_keyword) - *next_keyword = ','; - else - data = 0; - } return 0; } @@ -459,7 +198,8 @@ char * parse_server(char * unc_name) char * ipaddress_string = NULL; struct hostent * host_entry; struct in_addr server_ipaddr; - int rc; + int rc,j; + char temp[64]; if(length > 1023) { printf("mount error: UNC name too long"); @@ -476,21 +216,21 @@ char * parse_server(char * unc_name) printf("\nMounting the DFS root for domain not implemented yet"); return 0; } else { + /* BB add support for \\\\ not just // */ if(strncmp(unc_name,"//",2) && strncmp(unc_name,"\\\\",2)) { printf("mount error: improperly formatted UNC name."); printf(" %s does not begin with \\\\ or //\n",unc_name); return 0; } else { unc_name[0] = '\\'; - unc_name[0] = '/'; - unc_name[1] = '/'; + unc_name[1] = '\\'; unc_name += 2; if ((share = strchr(unc_name, '/')) || (share = strchr(unc_name,'\\'))) { *share = 0; /* temporarily terminate the string */ share += 1; host_entry = gethostbyname(unc_name); - *(share - 1) = '/'; /* put the slash back */ + *(share - 1) = '\\'; /* put the slash back */ /* rc = getipnodebyname(unc_name, AF_INET, AT_ADDRCONFIG ,&rc);*/ if(host_entry == NULL) { printf("mount error: could not find target server. TCP name %s not found ", unc_name); @@ -531,19 +271,21 @@ static struct option longopts[] = { { "rw", 0, 0, 'w' }, { "options", 1, 0, 'o' }, { "types", 1, 0, 't' }, - { "rsize",1, 0, 'R' }, - { "wsize",1, 0, 'W' }, - { "uid", 1, 0, '1'}, - { "gid", 1, 0, '2'}, + { "replace", 0, 0, 129 }, + { "after", 0, 0, 130 }, + { "before", 0, 0, 131 }, + { "over", 0, 0, 132 }, + { "move", 0, 0, 133 }, + { "rsize",1, 0, 136 }, + { "wsize",1, 0, 137 }, + { "uid", 1, 0, 138}, + { "gid", 1, 0, 139}, { "uuid",1,0,'U' }, - { "user",1,0,'u'}, - { "username",1,0,'u'}, - { "dom",1,0,'d'}, - { "domain",1,0,'d'}, - { "password",1,0,'p'}, - { "pass",1,0,'p'}, - { "credentials",1,0,'c'}, - { "port",1,0,'P'}, + { "user",1,0,140}, + { "username",1,0,140}, + { "dom",1,0,141}, + { "domain",1,0,141}, + { "password",1,0,142}, { NULL, 0, 0, 0 } }; @@ -558,15 +300,13 @@ int main(int argc, char ** argv) char * uuid = NULL; char * mountpoint; char * options; - char * temp; - int rc; + int rc,i; int rsize = 0; int wsize = 0; int nomtab = 0; int uid = 0; int gid = 0; int optlen = 0; - int orgoptlen = 0; struct stat statbuf; struct utsname sysinfo; struct mntent mountent; @@ -584,42 +324,58 @@ int main(int argc, char ** argv) uname(&sysinfo); /* BB add workstation name and domain and pass down */ - -/* #ifdef _GNU_SOURCE - printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname); -#endif */ - +/*#ifdef _GNU_SOURCE + printf(" node: %s machine: %s\n", sysinfo.nodename,sysinfo.machine); +#endif*/ + if(argc < 3) + mount_cifs_usage(); share_name = argv[1]; mountpoint = argv[2]; - /* add sharename in opts string as unc= parm */ while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsU:vVwt:", longopts, NULL)) != -1) { switch (c) { -/* No code to do the following options yet */ -/* case 'l': - list_with_volumelabel = 1; - break; - case 'L': - volumelabel = optarg; - break; */ /* case 'a': ++mount_all; + break; + case 'f': + ++fake; + break; + case 'F': + ++optfork; break; */ - - case '?': case 'h': /* help */ mount_cifs_usage (); - exit(1); - case 'n': - ++nomtab; - break; - case 'o': + break; +/* case 'i': + external_allowed = 0; + break; + case 'l': + list_with_volumelabel = 1; + break; + case 'L': + volumelabel = optarg; + break; */ + case 'n': + ++nomtab; + break; + case 'o': + if (orgoptions) { + orgoptions = strcat(orgoptions, ","); + orgoptions = strcat(orgoptions,optarg); + } else orgoptions = strdup(optarg); - break; + break; + +/* case 'O': + if (test_opts) + test_opts = xstrconcat3(test_opts, ",", optarg); + else + test_opts = xstrdup(optarg); + break;*/ case 'r': /* mount readonly */ - flags |= MS_RDONLY; + flags |= MS_RDONLY;; break; case 'U': uuid = optarg; @@ -627,113 +383,111 @@ int main(int argc, char ** argv) case 'v': ++verboseflag; break; - case 'V': - printf ("mount.cifs version: %s.%s%s\n", - MOUNT_CIFS_VERSION_MAJOR, - MOUNT_CIFS_VERSION_MINOR, - MOUNT_CIFS_VENDOR_SUFFIX); - if(mountpassword) { - memset(mountpassword,0,64); - } - exit (0); +/* case 'V': + printf ("mount: %s\n", version); + exit (0);*/ case 'w': - flags &= ~MS_RDONLY; + flags &= ~MS_RDONLY;; break; - case 'R': +/* case 0: + break; + + case 128: + mounttype = MS_BIND; + break; + case 129: + mounttype = MS_REPLACE; + break; + case 130: + mounttype = MS_AFTER; + break; + case 131: + mounttype = MS_BEFORE; + break; + case 132: + mounttype = MS_OVER; + break; + case 133: + mounttype = MS_MOVE; + break; + case 135: + mounttype = (MS_BIND | MS_REC); + break; */ + case 136: rsize = atoi(optarg) ; break; - case 'W': + case 137: wsize = atoi(optarg); break; - case '1': + case 138: uid = atoi(optarg); break; - case '2': + case 139: gid = atoi(optarg); break; - case 'u': + case 140: got_user = 1; user_name = optarg; break; - case 'd': + case 141: domain_name = optarg; break; - case 'p': - if(mountpassword == NULL) - mountpassword = calloc(65,1); - if(mountpassword) { - got_password = 1; - strncpy(mountpassword,optarg,64); - } - break; - case 't': + case 142: + got_password = 1; + mountpassword = optarg; break; + case '?': default: - printf("unknown mount option %c\n",c); - mount_cifs_usage(); - exit(1); - } - } - - if(argc < 3) - mount_cifs_usage(); - - if (getenv("PASSWD")) { - if(mountpassword == NULL) - mountpassword = calloc(65,1); - if(mountpassword) { - strncpy(mountpassword,getenv("PASSWD"),64); - got_password = 1; + mount_cifs_usage (); } - } else if (getenv("PASSWD_FD")) { - get_password_from_file(atoi(getenv("PASSWD_FD")),NULL); - } else if (getenv("PASSWD_FILE")) { - get_password_from_file(0, getenv("PASSWD_FILE")); } - ipaddr = parse_server(share_name); - - if (orgoptions && parse_options(orgoptions)) - return 1; - - /* BB save off path and pop after mount returns? */ - /* BB canonicalize the path in argv[1]? */ - - if(chdir(mountpoint)) { - printf("mount error: can not change directory into mount target %s\n",mountpoint); - } + /* canonicalize the path in argv[1]? */ if(stat (mountpoint, &statbuf)) { printf("mount error: mount point %s does not exist\n",mountpoint); return -1; } - if (S_ISDIR(statbuf.st_mode) == 0) { printf("mount error: mount point %s is not a directory\n",mountpoint); return -1; } - if((getuid() != 0) && (geteuid() == 0)) { - if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) { - printf("setuid mount allowed\n"); - } else { - printf("mount error: permission denied or not superuser and cifs.mount not installed SUID\n"); - return -1; - } + if(geteuid()) { + printf("mount error: permission denied, not superuser and cifs.mount not installed SUID\n"); + return -1; } + ipaddr = parse_server(share_name); +/* if(share_name == NULL) + return 1; */ + if (parse_options(strdup(orgoptions))) + return 1; + if(got_user == 0) user_name = getusername(); +/* check username for user%password format */ + if(got_password == 0) { - mountpassword = getpass("Password: "); /* BB obsolete */ - got_password = 1; + if (getenv("PASSWD")) { + mountpassword = malloc(33); + if(mountpassword) { + strncpy(mountpassword,getenv("PASSWD"),32); + got_password = 1; + } +/* } else if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) { + get_password_file(); + got_password = 1;*/ /* BB add missing function */ + } else { + mountpassword = getpass("Password: "); /* BB obsolete */ + got_password = 1; + } } /* FIXME launch daemon (handles dfs name resolution and credential change) remember to clear parms and overwrite password field before launching */ if(orgoptions) { optlen = strlen(orgoptions); - orgoptlen = optlen; } else optlen = 0; if(share_name) @@ -746,13 +500,9 @@ int main(int argc, char ** argv) optlen += strlen(mountpassword) + 6; options = malloc(optlen + 10); - options[0] = 0; + options[0] = 0; strncat(options,"unc=",4); strcat(options,share_name); - /* scan backwards and reverse direction of slash */ - temp = strrchr(options, '/'); - if(temp > options + 6) - *temp = '\\'; if(ipaddr) { strncat(options,",ip=",4); strcat(options,ipaddr); @@ -766,30 +516,26 @@ int main(int argc, char ** argv) strcat(options,mountpassword); } strncat(options,",ver=",5); - strcat(options,MOUNT_CIFS_VERSION_MAJOR); + strcat(options,MOUNT_CIFS_VERSION); if(orgoptions) { strcat(options,","); strcat(options,orgoptions); } - if(verboseflag) - printf("\ncifs.mount kernel mount options %s \n",options); + /* printf("\noptions %s \n",options);*/ if(mount(share_name, mountpoint, "cifs", flags, options)) { /* remember to kill daemon on error */ switch (errno) { case 0: printf("mount failed but no error number set\n"); - break; + return 0; case ENODEV: printf("mount error: cifs filesystem not supported by the system\n"); break; default: - printf("mount error %d = %s\n",errno,strerror(errno)); + printf("mount error %d = %s",errno,strerror(errno)); } printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); - if(mountpassword) { - memset(mountpassword,0,64); - } return -1; } else { pmntfile = setmntent(MOUNTED, "a+"); @@ -806,20 +552,6 @@ int main(int argc, char ** argv) printf("could not update mount table\n"); } } - if(mountpassword) { - memset(mountpassword,0,64); - free(mountpassword); - } - - if(options) { - memset(options,0,optlen); - free(options); - } - - if(orgoptions) { - memset(orgoptions,0,orgoptlen); - free(orgoptions); - } return 0; } diff --git a/source/client/smbmnt.c b/source/client/smbmnt.c index 753a31c3139..ce406179cfd 100644 --- a/source/client/smbmnt.c +++ b/source/client/smbmnt.c @@ -38,7 +38,7 @@ help(void) { printf("\n"); printf("Usage: smbmnt mount-point [options]\n"); - printf("Version %s\n\n",SAMBA_VERSION_STRING); + printf("Version %s\n\n",VERSION); printf("-s share share name on server\n" "-r mount read-only\n" "-u uid mount as uid\n" @@ -94,9 +94,9 @@ parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share) static char * fullpath(const char *p) { - char path[PATH_MAX+1]; + char path[MAXPATHLEN]; - if (strlen(p) > PATH_MAX) { + if (strlen(p) > MAXPATHLEN-1) { return NULL; } @@ -240,7 +240,7 @@ do_mount(char *share_name, unsigned int flags, struct smb_mount_data *data) data.dir_mode |= S_IXOTH; } - flags = MS_MGC_VAL | MS_NOSUID | MS_NODEV; + flags = MS_MGC_VAL; if (mount_ro) flags |= MS_RDONLY; diff --git a/source/client/smbmount.c b/source/client/smbmount.c index 6e8d9f5bca7..ac1a742ab72 100644 --- a/source/client/smbmount.c +++ b/source/client/smbmount.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" #include <mntent.h> @@ -27,7 +25,6 @@ #include <linux/smb_fs.h> extern BOOL in_client; -extern pstring user_socket_options; static pstring credentials; static pstring my_netbios_name; @@ -51,8 +48,6 @@ static unsigned mount_dmask; static BOOL use_kerberos; /* TODO: Add code to detect smbfs version in kernel */ static BOOL status32_smbfs = False; -static BOOL smbfs_has_unicode = False; -static BOOL smbfs_has_lfs = False; static void usage(void); @@ -203,14 +198,15 @@ static struct cli_state *do_connection(char *the_service) /* This should be right for current smbfs. Future versions will support large files as well as unicode and oplocks. */ - c->capabilities &= ~(CAP_NT_SMBS | CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS); - if (!smbfs_has_lfs) - c->capabilities &= ~CAP_LARGE_FILES; - if (!smbfs_has_unicode) - c->capabilities &= ~CAP_UNICODE; - if (!status32_smbfs) { - c->capabilities &= ~CAP_STATUS32; - c->force_dos_errors = True; + if (status32_smbfs) { + c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | + CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS); + } + else { + c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | + CAP_NT_FIND | CAP_STATUS32 | + CAP_LEVEL_II_OPLOCKS); + c->force_dos_errors = True; } if (!cli_session_setup(c, username, @@ -399,8 +395,8 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat } /* here we are no longer interactive */ - set_remote_machine_name("smbmount", False); /* sneaky ... */ - setup_logging("mount.smbfs", False); + set_remote_machine_name("smbmount"); /* sneaky ... */ + setup_logging("mount.smbfs", DEBUG_STDERR); reopen_logs(); DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid())); @@ -428,7 +424,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat **/ static void init_mount(void) { - char mount_point[PATH_MAX+1]; + char mount_point[MAXPATHLEN+1]; pstring tmp; pstring svc2; struct cli_state *c; @@ -663,7 +659,7 @@ static void usage(void) { printf("Usage: mount.smbfs service mountpoint [-o options,...]\n"); - printf("Version %s\n\n",SAMBA_VERSION_STRING); + printf("Version %s\n\n",VERSION); printf( "Options:\n\ @@ -684,8 +680,6 @@ static void usage(void) scope=<arg> NetBIOS scope\n\ iocharset=<arg> Linux charset (iso8859-1, utf8)\n\ codepage=<arg> server codepage (cp850)\n\ - unicode use unicode when communicating with server\n\ - lfs large file system support\n\ ttl=<arg> dircache time to live\n\ guest don't prompt for a password\n\ ro mount read-only\n\ @@ -802,9 +796,9 @@ static void parse_mount_smb(int argc, char **argv) } else if(!strcmp(opts, "workgroup")) { pstrcpy(workgroup,opteq+1); } else if(!strcmp(opts, "sockopt")) { - pstrcpy(user_socket_options,opteq+1); + lp_set_cmdline("socket options", opteq+1); } else if(!strcmp(opts, "scope")) { - set_global_scope(opteq+1); + lp_set_cmdline("netbios scope", opteq+1); } else { slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1); p += strlen(p); @@ -831,10 +825,6 @@ static void parse_mount_smb(int argc, char **argv) mount_ro = 0; } else if(!strcmp(opts, "ro")) { mount_ro = 1; - } else if(!strcmp(opts, "unicode")) { - smbfs_has_unicode = True; - } else if(!strcmp(opts, "lfs")) { - smbfs_has_lfs = True; } else { strncpy(p, opts, sizeof(pstring) - (p - options) - 1); p += strlen(opts); @@ -867,7 +857,7 @@ static void parse_mount_smb(int argc, char **argv) DEBUGLEVEL = 1; /* here we are interactive, even if run from autofs */ - setup_logging("mount.smbfs",True); + setup_logging("mount.smbfs",DEBUG_STDERR); #if 0 /* JRA - Urban says not needed ? */ /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default @@ -891,7 +881,7 @@ static void parse_mount_smb(int argc, char **argv) got_pass = True; memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password)); } - strupper_m(username); + strupper(username); } if (getenv("PASSWD")) { @@ -923,7 +913,7 @@ static void parse_mount_smb(int argc, char **argv) read_credentials_file(credentials); } - DEBUG(3,("mount.smbfs started (version %s)\n", SAMBA_VERSION_STRING)); + DEBUG(3,("mount.smbfs started (version %s)\n", VERSION)); if (*workgroup == 0) { pstrcpy(workgroup,lp_workgroup()); @@ -933,7 +923,7 @@ static void parse_mount_smb(int argc, char **argv) if (!*my_netbios_name) { pstrcpy(my_netbios_name, myhostname()); } - strupper_m(my_netbios_name); + strupper(my_netbios_name); init_mount(); return 0; diff --git a/source/client/smbspool.c b/source/client/smbspool.c index 5daefec5a55..24d40114f0b 100644 --- a/source/client/smbspool.c +++ b/source/client/smbspool.c @@ -20,8 +20,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /* @@ -184,7 +182,7 @@ static int smb_print(struct cli_state *, char *, FILE *); * Setup the SAMBA server state... */ - setup_logging("smbspool", True); + setup_logging("smbspool", DEBUG_STDOUT); in_client = True; /* Make sure that we tell lp_load we are */ @@ -272,18 +270,19 @@ smb_connect(const char *workgroup, /* I - Workgroup */ const char *password) /* I - Password */ { struct cli_state *c; /* New connection */ - pstring myname; /* Client name */ + char *myname; /* Client name */ NTSTATUS nt_status; /* * Get the names and addresses of the client and server... */ - get_myname(myname); + myname = get_myname(); nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????", - username, workgroup, password, 0, Undefined, NULL); + username, workgroup, password, 0, NULL); + free(myname); if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status)); return NULL; diff --git a/source/client/tree.c b/source/client/tree.c index 97ad7742e31..94fd93c2106 100644 --- a/source/client/tree.c +++ b/source/client/tree.c @@ -36,7 +36,7 @@ struct tree_data { }; -static void tree_error_message(gchar *message) { +void error_message(gchar *message) { GtkWidget *dialog, *label, *okay_button; @@ -69,7 +69,7 @@ static void tree_error_message(gchar *message) { * workgroup type and return a path from there */ -static pstring path_string; +static char path_string[1024]; char *get_path(GtkWidget *item) { @@ -112,7 +112,7 @@ char *get_path(GtkWidget *item) * Now, build the path */ - pstrcpy( path_string, "smb:/" ); + snprintf(path_string, sizeof(path_string), "smb:/"); for (j = i - 1; j >= 0; j--) { @@ -151,7 +151,7 @@ static void cb_select_child (GtkWidget *root_tree, GtkWidget *child, char dirbuf[512]; struct smbc_dirent *dirp; struct stat st1; - pstring path, path1; + char path[1024], path1[1024]; g_print ("select_child called for root tree %p, subtree %p, child %p\n", root_tree, subtree, child); @@ -344,7 +344,7 @@ static void cb_itemsignal( GtkWidget *item, slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not open dir %s, %s\n", get_path(item), strerror(errno)); - tree_error_message(errmsg); + error_message(errmsg); /* gtk_main_quit();*/ @@ -363,7 +363,7 @@ static void cb_itemsignal( GtkWidget *item, slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not read dir smbc://, %s\n", strerror(errno)); - tree_error_message(errmsg); + error_message(errmsg); /* gtk_main_quit();*/ |