From 607e3022381ab089bfcc0b153461b6b3ac76f175 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Nov 2004 05:37:57 +0000 Subject: r4013: got rid of a bunch of unused or unmaintained code - removed the clitar code. It is unmaintained, and a horribly badly done hack - removed client.h as it contained mostly unused definitions - removed the unused clidfs.c code (This used to be commit 31a7bddbb3815b4d625e993dbce4805dae1c18f8) --- source4/client/client.c | 83 +- source4/client/clitar.c | 1896 ------------------------------------------- source4/client/config.mk | 3 +- source4/include/client.h | 117 --- source4/include/clilist.h | 28 + source4/include/structs.h | 2 +- source4/libcli/clideltree.c | 8 +- source4/libcli/clidfs.c | 558 ------------- source4/libcli/clilist.c | 49 +- source4/torture/basic/dir.c | 2 +- source4/torture/masktest.c | 4 +- source4/torture/torture.c | 6 +- 12 files changed, 80 insertions(+), 2676 deletions(-) delete mode 100644 source4/client/clitar.c delete mode 100644 source4/include/client.h create mode 100644 source4/include/clilist.h delete mode 100644 source4/libcli/clidfs.c diff --git a/source4/client/client.c b/source4/client/client.c index 1a357fbbd5..b438e986cd 100644 --- a/source4/client/client.c +++ b/source4/client/client.c @@ -23,7 +23,7 @@ #include "includes.h" #include "dynconfig.h" -#include "client.h" +#include "clilist.h" #include "lib/cmdline/popt_common.h" #include "librpc/gen_ndr/ndr_srvsvc.h" #include "libcli/raw/libcliraw.h" @@ -174,7 +174,7 @@ static int readfile(char *b, int n, XFILE *f) return x_fread(b,1,n,f); i = 0; - while (i < (n - 1) && (i < CLI_BUFFER_SIZE)) { + while (i < (n - 1)) { if ((c = x_getc(f)) == EOF) { break; } @@ -358,9 +358,9 @@ BOOL mask_match(struct smbcli_state *c, const char *string, char *pattern, /******************************************************************* decide if a file should be operated on ********************************************************************/ -static BOOL do_this_one(struct file_info *finfo) +static BOOL do_this_one(struct clilist_file_info *finfo) { - if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) return(True); + if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) return(True); if (*fileselection && !mask_match(cli, finfo->name,fileselection,False)) { @@ -373,7 +373,7 @@ static BOOL do_this_one(struct file_info *finfo) return(False); } - if ((archive_level==1 || archive_level==2) && !(finfo->mode & FILE_ATTRIBUTE_ARCHIVE)) { + if ((archive_level==1 || archive_level==2) && !(finfo->attrib & FILE_ATTRIBUTE_ARCHIVE)) { DEBUG(3,("archive %s failed\n", finfo->name)); return(False); } @@ -384,11 +384,11 @@ static BOOL do_this_one(struct file_info *finfo) /**************************************************************************** display info about a file ****************************************************************************/ -static void display_finfo(struct file_info *finfo) +static void display_finfo(struct clilist_file_info *finfo) { if (do_this_one(finfo)) { time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */ - char *astr = attrib_string(NULL, finfo->mode); + char *astr = attrib_string(NULL, finfo->attrib); d_printf(" %-30s%7.7s %8.0f %s", finfo->name, astr, @@ -403,7 +403,7 @@ static void display_finfo(struct file_info *finfo) /**************************************************************************** accumulate size of a file ****************************************************************************/ -static void do_du(struct file_info *finfo) +static void do_du(struct clilist_file_info *finfo) { if (do_this_one(finfo)) { dir_total += finfo->size; @@ -416,7 +416,7 @@ static char *do_list_queue = 0; static long do_list_queue_size = 0; static long do_list_queue_start = 0; static long do_list_queue_end = 0; -static void (*do_list_fn)(struct file_info *); +static void (*do_list_fn)(struct clilist_file_info *); /**************************************************************************** functions for do_list_queue @@ -535,9 +535,9 @@ static int do_list_queue_empty(void) /**************************************************************************** a helper for do_list ****************************************************************************/ -static void do_list_helper(struct file_info *f, const char *mask, void *state) +static void do_list_helper(struct clilist_file_info *f, const char *mask, void *state) { - if (f->mode & FILE_ATTRIBUTE_DIRECTORY) { + if (f->attrib & FILE_ATTRIBUTE_DIRECTORY) { if (do_list_dirs && do_this_one(f)) { do_list_fn(f); } @@ -567,7 +567,8 @@ static void do_list_helper(struct file_info *f, const char *mask, void *state) /**************************************************************************** a wrapper around smbcli_list that adds recursion ****************************************************************************/ -void do_list(const char *mask,uint16_t attribute,void (*fn)(struct file_info *),BOOL rec, BOOL dirs) +void do_list(const char *mask,uint16_t attribute, + void (*fn)(struct clilist_file_info *),BOOL rec, BOOL dirs) { static int in_do_list = 0; @@ -882,7 +883,7 @@ static BOOL yesno(char *p) /**************************************************************************** do a mget operation on one file ****************************************************************************/ -static void do_mget(struct file_info *finfo) +static void do_mget(struct clilist_file_info *finfo) { pstring rname; pstring quest; @@ -897,7 +898,7 @@ static void do_mget(struct file_info *finfo) return; } - if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) + if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) slprintf(quest,sizeof(pstring)-1, "Get directory %s? ",finfo->name); else @@ -906,7 +907,7 @@ static void do_mget(struct file_info *finfo) if (prompt && !yesno(quest)) return; - if (!(finfo->mode & FILE_ATTRIBUTE_DIRECTORY)) { + if (!(finfo->attrib & FILE_ATTRIBUTE_DIRECTORY)) { pstrcpy(rname,cur_dir); pstrcat(rname,finfo->name); do_get(rname, finfo->name, False); @@ -2386,7 +2387,6 @@ static struct {"acl",cmd_acl," show file ACL",{COMPL_NONE,COMPL_NONE}}, {"allinfo",cmd_allinfo," show all possible info about a file",{COMPL_NONE,COMPL_NONE}}, {"archive",cmd_archive,"\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 (default 20)",{COMPL_NONE,COMPL_NONE}}, {"cancel",cmd_cancel," cancel a print queue entry",{COMPL_NONE,COMPL_NONE}}, {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}}, {"chmod",cmd_chmod," chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_REMOTE}}, @@ -2426,10 +2426,7 @@ static struct {"reput",cmd_reput," [remote name] put a file restarting at end of remote file",{COMPL_LOCAL,COMPL_REMOTE}}, {"rm",cmd_del," delete all matching files",{COMPL_REMOTE,COMPL_NONE}}, {"rmdir",cmd_rmdir," remove a directory",{COMPL_NONE,COMPL_NONE}}, - {"setmode",cmd_setmode,"filename change modes of file",{COMPL_REMOTE,COMPL_NONE}}, {"symlink",cmd_symlink," create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}}, - {"tar",cmd_tar,"tar [IXFqbgNan] current directory to/from ",{COMPL_NONE,COMPL_NONE}}, - {"tarmode",cmd_tarmode," tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}}, {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}}, /* Yes, this must be here, see crh's comment above. */ @@ -2550,12 +2547,12 @@ typedef struct { int len; } completion_remote_t; -static void completion_remote_filter(struct file_info *f, const char *mask, void *state) +static void completion_remote_filter(struct clilist_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 & FILE_ATTRIBUTE_DIRECTORY)) + if ((info->dirmask[0] == 0) && !(f->attrib & FILE_ATTRIBUTE_DIRECTORY)) info->matches[info->count] = strdup(f->name); else { pstring tmp; @@ -2565,13 +2562,13 @@ static void completion_remote_filter(struct file_info *f, const char *mask, void else tmp[0] = 0; pstrcat(tmp, f->name); - if (f->mode & FILE_ATTRIBUTE_DIRECTORY) + if (f->attrib & FILE_ATTRIBUTE_DIRECTORY) pstrcat(tmp, "/"); info->matches[info->count] = strdup(tmp); } if (info->matches[info->count] == NULL) return; - if (f->mode & FILE_ATTRIBUTE_DIRECTORY) + if (f->attrib & FILE_ATTRIBUTE_DIRECTORY) smb_readline_ca_char(0); if (info->count == 1) @@ -2911,31 +2908,6 @@ static int do_host_query(char *query_host) } -/**************************************************************************** -handle a tar operation -****************************************************************************/ -static int do_tar_op(char *base_directory) -{ - int ret; - - /* do we already have a connection? */ - if (!cli) { - cli = do_connect(desthost, service); - if (!cli) - return 1; - } - - recurse=True; - - if (*base_directory) do_cd(base_directory); - - ret=process_tar(); - - smbcli_shutdown(cli); - - return(ret); -} - /**************************************************************************** handle a message operation ****************************************************************************/ @@ -2997,7 +2969,6 @@ static void remember_query_host(const char *arg, int opt; pstring query_host; BOOL message = False; - extern char tar_type; pstring term_code; poptContext pc; char *p; @@ -3011,7 +2982,6 @@ static void remember_query_host(const char *arg, { "stderr", 'E', POPT_ARG_NONE, NULL, 'E', "Write messages to stderr instead of stdout" }, { "list", 'L', POPT_ARG_STRING, NULL, 'L', "Get a list of shares available on a host", "HOST" }, { "terminal", 't', POPT_ARG_STRING, NULL, 't', "Terminal I/O code {sjis|euc|jis7|jis8|junet|hex}", "CODE" }, - { "tar", 'T', POPT_ARG_STRING, NULL, 'T', "Command line tar", "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, NULL, 'b', "Changes the transmit/send buffer", "BYTES" }, @@ -3074,12 +3044,6 @@ static void remember_query_host(const char *arg, case 't': pstrcpy(term_code, poptGetOptArg(pc)); break; - case 'T': - if (!tar_parseargs(argc, argv, poptGetOptArg(pc), optind)) { - poptPrintUsage(pc, stderr, 0); - exit(1); - } - break; case 'D': fstrcpy(base_directory,poptGetOptArg(pc)); break; @@ -3111,7 +3075,7 @@ static void remember_query_host(const char *arg, /*init_names(); */ - if (!tar_type && !*query_host && !*service && !message) { + if (!*query_host && !*service && !message) { poptPrintUsage(pc, stderr, 0); exit(1); } @@ -3125,11 +3089,6 @@ static void remember_query_host(const char *arg, 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 ((p=strchr_m(query_host,'#'))) { *p = 0; diff --git a/source4/client/clitar.c b/source4/client/clitar.c deleted file mode 100644 index 476e29d4ba..0000000000 --- a/source4/client/clitar.c +++ /dev/null @@ -1,1896 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Tar Extensions - Copyright (C) Ricky Poulten 1995-1998 - Copyright (C) Richard Sharpe 1998 - - 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. -*/ -/* The following changes developed by Richard Sharpe for Canon Information - Systems Research Australia (CISRA) - - 1. Restore can now restore files with long file names - 2. Save now saves directory information so that we can restore - directory creation times - 3. tar now accepts both UNIX path names and DOS path names. I prefer - those lovely /'s to those UGLY \'s :-) - 4. the files to exclude can be specified as a regular expression by adding - an r flag to the other tar flags. Eg: - - -TcrX file.tar "*.(obj|exe)" - - will skip all .obj and .exe files -*/ - - -#include "includes.h" -#include "client.h" -#include "clitar.h" -#include "system/time.h" -#include "system/iconv.h" -#include "system/filesys.h" - -/** - Convert list of tokens to array; dependent on above routine. -**/ -static char **toktocliplist(char *ptr, int *ctok, const char *sep) -{ - char *s = ptr; - int ictok=0; - char **ret, **iret; - - if (!sep) - sep = " \t\n\r"; - - while(*s && strchr_m(sep,*s)) - s++; - - /* nothing left? */ - if (!*s) - return(NULL); - - do { - ictok++; - while(*s && (!strchr_m(sep,*s))) - s++; - while(*s && strchr_m(sep,*s)) - *s++=0; - } while(*s); - - *ctok=ictok; - s = ptr; - - if (!(ret=iret=malloc(ictok*sizeof(char *)))) - return NULL; - - while(ictok--) { - *iret++=s; - while(*s++) - ; - while(!*s) - s++; - } - - return ret; -} - -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 -{ - uint64_t size; - uint16_t 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; - -} stack; - -#define SEPARATORS " \t\n\r" -extern struct smbcli_state *cli; - -/* These defines are for the do_setrattr routine, to indicate - * setting and reseting of file attributes in the function call */ -#define ATTRSET 1 -#define ATTRRESET 0 - -static uint16_t attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; - -#ifndef CLIENT_TIMEOUT -#define CLIENT_TIMEOUT (30*1000) -#endif - -static char *tarbuf, *buffer_p; -static int tp, ntarf, tbufsiz; -static double ttarf; -/* Incremental mode */ -static BOOL tar_inc=False; -/* Reset archive bit */ -static BOOL tar_reset=False; -/* Include / exclude mode (true=include, false=exclude) */ -static BOOL tar_excl=True; -/* use regular expressions for search on file names */ -static BOOL tar_re_search=False; -#ifdef HAVE_REGEX_H -regex_t *preg; -#endif -/* Do not dump anything, just calculate sizes */ -static BOOL dry_run=False; -/* Dump files with System attribute */ -static BOOL tar_system=True; -/* Dump files with Hidden attribute */ -static BOOL tar_hidden=True; -/* Be noisy - make a catalogue */ -static BOOL tar_noisy=True; -static BOOL tar_real_noisy=False; /* Don't want to be really noisy by default */ - -char tar_type='\0'; -static char **cliplist=NULL; -static int clipn=0; -static BOOL must_free_cliplist = False; - -extern BOOL lowercase; -extern uint16_t cnum; -extern BOOL readbraw_supported; -extern int max_xmit; -extern pstring cur_dir; -extern int get_total_time_ms; -extern int get_total_size; - -static int blocksize=20; -static int tarhandle; - -static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime, - const char *amode, uint8_t ftype); -static void do_atar(char *rname,const char *lname,struct file_info *finfo1); -static void do_tar(struct file_info *finfo); -static void oct_it(uint64_t value, int ndgs, char *p); -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); -static void initarbuf(void); - -/* restore functions */ -static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix); -static long unoct(char *p, int ndgs); -static void do_tarput(void); -static void unfixtarname(char *tptr, char *fp, int l, BOOL first); - -/* - * tar specific utitlities - */ - -/******************************************************************* -Create a string of size size+1 (for the null) -*******************************************************************/ -static char *string_create_s(int size) -{ - char *tmp; - - tmp = (char *)malloc(size+1); - - if (tmp == NULL) { - - DEBUG(0, ("Out of memory in string_create_s\n")); - - } - - return(tmp); - -} - -/**************************************************************************** -Write a tar header to buffer -****************************************************************************/ -static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime, - const char *amode, uint8_t ftype) -{ - union hblock hb; - int i, chk, l; - char *jp; - - DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname)); - - memset(hb.dummy, 0, sizeof(hb.dummy)); - - 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((uint64_t)0, 8, hb.dbuf.uid); - oct_it((uint64_t)0, 8, hb.dbuf.gid); - oct_it((uint64_t) size, 13, hb.dbuf.size); - oct_it((uint64_t) 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++); - - oct_it((uint64_t) chk, 8, hb.dbuf.chksum); - hb.dbuf.chksum[6] = '\0'; - - (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; - - /* - * 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++); - - 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++); - - chk += ' ' * 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)); - - if (fchk != chk) - { - DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk)); - dump_data(5, (uint8_t *)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); - - } - - 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; - } - - 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 */ - - 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; - } -} - -/**************************************************************************** -Malloc tape buffer -****************************************************************************/ -static void initarbuf(void) -{ - /* 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; -} - -/**************************************************************************** -Write two zero blocks at end of file -****************************************************************************/ -static void dotareof(int f) -{ - struct stat stbuf; - /* Two zero blocks at end of file, write out full buffer */ - - if (dry_run) - return; - - (void) dozerobuf(f, TBLOCK); - (void) dozerobuf(f, TBLOCK); - - if (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); -} - -/**************************************************************************** -(Un)mangle DOS pathname, make nonabsolute -****************************************************************************/ -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++='.'; - - safe_strcpy(tptr, fp, l); - string_replace(tptr, '\\', '/'); -} - -/**************************************************************************** -Convert from decimal to octal string -****************************************************************************/ -static void oct_it (uint64_t value, int ndgs, char *p) -{ - /* Converts long to octal string, pads with leading zeros */ - - /* 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); - - /* 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 */ - - while (--ndgs) - { - if (isdigit((int)*p)) - value = (value << 3) | (long) (*p - '0'); - - p++; - } - - return value; -} - -/**************************************************************************** -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; - - 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; - - /* 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; - - 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 */ - - char *partpath, *ffname; - char *p=fname, *basehack; - - DEBUG(5, ( "Ensurepath called with: %s\n", 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); - - } - - *partpath = 0; - - /* fname copied to ffname so can strtok */ - - safe_strcpy(ffname, fname, strlen(fname)); - - /* 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'; - - p=strtok(ffname, "\\"); - - while (p) - { - safe_strcat(partpath, p, strlen(fname) + 1); - - if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, partpath))) { - if (NT_STATUS_IS_ERR(smbcli_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; -} - -static int padit(char *buf, int bufsize, int padsize) -{ - int berr= 0; - int bytestowrite; - - DEBUG(5, ("Padding with %d zeros\n", padsize)); - memset(buf, 0, bufsize); - while( !berr && padsize > 0 ) { - bytestowrite= MIN(bufsize, padsize); - berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite; - padsize -= bytestowrite; - } - - return berr; -} - - -static void do_setrattr(char *name, uint16_t attr, int set) -{ - uint16_t oldattr; - - if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, name, &oldattr, NULL, NULL))) - return; - - if (set == ATTRSET) { - attr |= oldattr; - } else { - attr = oldattr & ~attr; - } - - if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, name, attr, 0))) { - DEBUG(1,("setatr failed: %s\n", smbcli_errstr(cli->tree))); - } -} - - -/**************************************************************************** -append one remote file to the tar file -***************************************************************************/ -static void do_atar(char *rname,const char *lname,struct file_info *finfo1) -{ - int fnum; - uint64_t 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 = discard_const_p(char, finfo1 -> name); - } - else { - ZERO_STRUCT(finfo); - } - - 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 = smbcli_open(cli->tree, rname, O_RDONLY, DENY_NONE); - - dos_clean_name(rname); - - if (fnum == -1) { - DEBUG(0,("%s opening remote file %s (%s)\n", - smbcli_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(smbcli_getattrE(cli->tree, fnum, &finfo.mode, &size, NULL, &finfo.atime, &finfo.mtime))) { - DEBUG(0, ("getattrE: %s\n", smbcli_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); - - while (nread < finfo.size && !close_done) { - - DEBUG(3,("nread=%.0f\n",(double)nread)); - - datalen = smbcli_read(cli->tree, fnum, data, nread, read_size); - - if (datalen == -1) { - DEBUG(0,("Error reading file %s : %s\n", rname, smbcli_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; - } - - 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++; - } - - smbcli_close(cli->tree, fnum); - - 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, 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)))); - } -} - -/**************************************************************************** -Append single file to tar file (or not) -***************************************************************************/ -static void do_tar(struct file_info *finfo) -{ - pstring rname; - - if (strequal(finfo->name,"..") || strequal(finfo->name,".")) - return; - - /* Is it on the exclude list ? */ - if (!tar_excl && clipn) { - pstring exclaim; - - DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir))); - - safe_strcpy(exclaim, cur_dir, sizeof(pstring)); - *(exclaim+strlen(exclaim)-1)='\0'; - - safe_strcat(exclaim, "\\", sizeof(pstring)); - safe_strcat(exclaim, finfo->name, sizeof(exclaim)); - - DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); - - if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) || -#ifdef HAVE_REGEX_H - (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) { -#else - (tar_re_search && mask_match(cli, exclaim, cliplist[0], True))) { -#endif - 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 - * dos \'s in path. Kill any absolute path names. But only if first! - */ - - DEBUG(5, ("firstb=%lX, secondb=%lX, len=%i\n", (long)tptr, (long)fp, l)); - - if (first) { - if (*fp == '.') { - fp++; - l--; - } - if (*fp == '\\' || *fp == '/') { - fp++; - l--; - } - } - - safe_strcpy(tptr, fp, l); - 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 - * 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); - -} - -/* Skip a file, even if it includes a long file name? */ -static int skip_file(int skipsize) -{ - int dsize = skipsize; - - DEBUG(5, ("Skiping file. Size = %i\n", skipsize)); - - /* 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; - - } - - return(True); -} - -/************************************************************* - Get a file from the tar file and store it. - When this is called, tarbuf already contains the first - file block. This is a bit broken & needs fixing. -**************************************************************/ - -static int get_file(file_info2 finfo) -{ - int fnum = -1, pos = 0, dsize = 0, rsize = 0, bpos = 0; - - DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, (int)finfo.size)); - - if (ensurepath(finfo.name) && - (fnum=smbcli_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 */ - - rsize = finfo.size; /* This is how much to write */ - - 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)); - - if (smbcli_write(cli->tree, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) { - DEBUG(0, ("Error writing remote file\n")); - return 0; - } - - rsize -= dsize; - pos += dsize; - - /* Now figure out how much to move in the buffer */ - - /* FIXME, we should skip more than one block at a time */ - - /* First, skip any initial part of the part written that is left over */ - /* from the end of the first TBLOCK */ - - if ((bpos) && ((bpos + dsize) >= TBLOCK)) { - - dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */ - bpos = 0; - - 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; - - } - - } - - /* - * Bugfix from Bob Boehmer . - * 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(). - */ - - while (((rsize != 0) && (dsize >= TBLOCK)) || - ((rsize == 0) && (dsize > TBLOCK))) { - - 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 ... */ - - if (NT_STATUS_IS_ERR(smbcli_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(smbcli_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 - is no file associated with a directory -*/ -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); - -} -/* 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) -{ - 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 = %d\n", (int)finfo.size)); - - if (longname == NULL) { - - DEBUG(0, ("could not allocate buffer of size %d for longname\n", - (int)(finfo.size + strlen(cur_dir) + 2))); - return(NULL); - } - - /* First, add cur_dir to the long file name */ - - if (strlen(cur_dir) > 0) { - strncpy(longname, cur_dir, namesize); - offset = strlen(cur_dir); - } - - /* 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); - -} - -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; - - } - - 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 ... */ - - /* 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))); -#else - || (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; - - } - - /* 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 - * 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 - */ - -/**************************************************************************** -Blocksize command -***************************************************************************/ -int cmd_block(const char **cmd_ptr) -{ - fstring buf; - int block; - - if (!next_token(cmd_ptr,buf,NULL,sizeof(buf))) - { - DEBUG(0, ("blocksize \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(const char **cmd_ptr) -{ - fstring buf; - - while (next_token(cmd_ptr,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(const char **cmd_ptr) -{ - char *q; - fstring buf; - pstring fname; - uint16_t attra[2]; - int direct=1; - - attra[0] = attra[1] = 0; - - if (!next_token(cmd_ptr,buf,NULL,sizeof(buf))) - { - DEBUG(0, ("setmode <[+|-]rsha>\n")); - return 1; - } - - safe_strcpy(fname, cur_dir, sizeof(pstring)); - safe_strcat(fname, buf, sizeof(pstring)); - - while (next_token(cmd_ptr,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 \n")); - return 1; - } - } - - if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) - { - DEBUG(0, ("setmode <[+|-]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); - - return 0; -} - -/**************************************************************************** -Principal command for creating / extracting -***************************************************************************/ -int cmd_tar(const char **cmd_ptr) -{ - fstring buf; - char **argl; - int argcl; - - if (!next_token(cmd_ptr,buf,NULL,sizeof(buf))) - { - DEBUG(0,("tar [IXbgan] \n")); - return 1; - } - - argl=toktocliplist(discard_const_p(char, *cmd_ptr), &argcl, NULL); - if (!tar_parseargs(argcl, argl, buf, 0)) - return 1; - - process_tar(); - - SAFE_FREE(argl); - - return 0; -} - -/**************************************************************************** -Command line (option) version -***************************************************************************/ -int process_tar(void) -{ - initarbuf(); - switch(tar_type) { - case 'x': - -#if 0 - do_tarput2(); -#else - 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= 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; - } - - /* 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) -{ - 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 { - struct stat stbuf; - extern time_t newer_than; - - if (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; - } - } - 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 || !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 = open(argv[Optind], O_RDONLY, 0)) == -1) - || (tar_type=='c' && (tarhandle=creat(argv[Optind], 0644)) < 0)) - { - DEBUG(0,("Error opening local file %s - %s\n", - argv[Optind], strerror(errno))); - return(0); - } - } - - return 1; -} diff --git a/source4/client/config.mk b/source4/client/config.mk index f3dc35f030..a04bb43f29 100644 --- a/source4/client/config.mk +++ b/source4/client/config.mk @@ -4,8 +4,7 @@ # Start BINARY smbclient [BINARY::smbclient] OBJ_FILES = \ - client/client.o \ - client/clitar.o + client/client.o REQUIRED_SUBSYSTEMS = \ CONFIG \ LIBCMDLINE \ diff --git a/source4/include/client.h b/source4/include/client.h deleted file mode 100644 index d3c1756045..0000000000 --- a/source4/include/client.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Luke Kenneth Casson Leighton 1996-1998 - Copyright (C) Jeremy Allison 1998 - Copyright (C) James Myers 2003 - - 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 _CLIENT_H -#define _CLIENT_H - -/* the client asks for a smaller buffer to save ram and also to get more - overlap on the wire. This size gives us a nice read/write size, which - will be a multiple of the page size on almost any system */ -#define CLI_BUFFER_SIZE (0xFFFF) -#define SMBCLI_DFS_MAX_REFERRAL_LEVEL 3 - -#define SAFETY_MARGIN 1024 -#define LARGE_WRITEX_HDR_SIZE 65 - - -/* - * These definitions depend on smb.h - */ - -struct file_info -{ - uint64_t size; - uint16_t mode; - uid_t uid; - gid_t gid; - /* these times are normally kept in GMT */ - time_t mtime; - time_t atime; - time_t ctime; - const char *name; - char short_name[13*3]; /* the *3 is to cope with multi-byte */ -}; - -struct print_job_info -{ - uint16_t id; - uint16_t priority; - size_t size; - fstring user; - fstring name; - time_t t; -}; - -typedef struct referral_info -{ - int server_type; - int referral_flags; - int proximity; - int ttl; - int pathOffset; - int altPathOffset; - int nodeOffset; - char *path; - char *altPath; - char *node; - char *host; - char *share; -} referral_info; - -typedef struct dfs_info -{ - int path_consumed; - int referral_flags; - int selected_referral; - int number_referrals; - referral_info referrals[10]; -} dfs_info; - -/* Internal client error codes for smbcli_request_context.internal_error_code */ -#define SMBCLI_ERR_INVALID_TRANS_RESPONSE 100 - -#define DFS_MAX_CLUSTER_SIZE 8 -/* client_context: used by cliraw callers to maintain Dfs - * state across multiple Dfs servers - */ -struct cli_client -{ - const char* sockops; - char* username; - char* password; - char* workgroup; - TALLOC_CTX *mem_ctx; - int number_members; - BOOL use_dfs; /* True if client should support Dfs */ - int connection_flags; /* see CLI_FULL_CONN.. below */ - uint16_t max_xmit_frag; - uint16_t max_recv_frag; - struct smbcli_state *cli[DFS_MAX_CLUSTER_SIZE]; -}; - -#define SMBCLI_FULL_CONNECTION_DONT_SPNEGO 0x0001 -#define SMBCLI_FULL_CONNECTION_USE_KERBEROS 0x0002 -#define SMBCLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK 0x0004 -#define SMBCLI_FULL_CONNECTION_USE_DFS 0x0008 - -#endif /* _CLIENT_H */ diff --git a/source4/include/clilist.h b/source4/include/clilist.h new file mode 100644 index 0000000000..d031987768 --- /dev/null +++ b/source4/include/clilist.h @@ -0,0 +1,28 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2004 + + 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. +*/ + +struct clilist_file_info { + uint64_t size; + uint16_t attrib; + time_t mtime; + const char *name; + const char *short_name; +}; + diff --git a/source4/include/structs.h b/source4/include/structs.h index 4204cdab15..9a2c965671 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -108,7 +108,7 @@ union libnet_RemoteTOD; struct net_functable; struct net_context; -struct file_info; +struct clilist_file_info; struct xattr_DosEAs; struct xattr_DosStreams; diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c index 7dd3803735..30369b977f 100644 --- a/source4/libcli/clideltree.c +++ b/source4/libcli/clideltree.c @@ -19,7 +19,7 @@ */ #include "includes.h" -#include "client.h" +#include "clilist.h" struct delete_state { struct smbcli_tree *tree; @@ -30,7 +30,7 @@ struct delete_state { /* callback function for torture_deltree() */ -static void delete_fn(struct file_info *finfo, const char *name, void *state) +static void delete_fn(struct clilist_file_info *finfo, const char *name, void *state) { struct delete_state *dstate = state; char *s, *n; @@ -41,14 +41,14 @@ static void delete_fn(struct file_info *finfo, const char *name, void *state) n[strlen(n)-1] = 0; asprintf(&s, "%s%s", n, finfo->name); - if (finfo->mode & FILE_ATTRIBUTE_READONLY) { + if (finfo->attrib & FILE_ATTRIBUTE_READONLY) { if (NT_STATUS_IS_ERR(smbcli_setatr(dstate->tree, s, 0, 0))) { DEBUG(2,("Failed to remove READONLY on %s - %s\n", s, smbcli_errstr(dstate->tree))); } } - if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) { + if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) { char *s2; asprintf(&s2, "%s\\*", s); smbcli_unlink(dstate->tree, s2); diff --git a/source4/libcli/clidfs.c b/source4/libcli/clidfs.c deleted file mode 100644 index c007d061a9..0000000000 --- a/source4/libcli/clidfs.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Dfs routines - Copyright (C) James Myers 2003 - - 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. -*/ - -#include "includes.h" - -BOOL smbcli_client_initialize(struct smbcli_client* context, - const char* sockops, - char* username, char* password, char* workgroup, - int flags) -{ - int i; - for (i=0; i < DFS_MAX_CLUSTER_SIZE ; i++) { - context->cli[i] = smbcli_raw_initialise(); - } - context->sockops = sockops; - context->username = username; - context->password = password; - context->workgroup = workgroup; - context->connection_flags = flags; - if (flags & SMBCLI_FULL_CONNECTION_USE_DFS) - context->use_dfs = True; - context->number_members = DFS_MAX_CLUSTER_SIZE; - return True; -} - -/**************************************************************************** - Interpret a Dfs referral structure. - The length of the structure is returned - The structure of a Dfs referral depends on the info level. -****************************************************************************/ - -static int interpret_referral(struct smbcli_state *cli, - int level,char *p,referral_info *rinfo) -{ - char* q; - int version, size; - - version = SVAL(p,0); - size = SVAL(p,2); - rinfo->server_type = SVAL(p,4); - rinfo->referral_flags = SVAL(p,6); - rinfo->proximity = SVAL(p,8); - rinfo->ttl = SVAL(p,10); - rinfo->pathOffset = SVAL(p,12); - rinfo->altPathOffset = SVAL(p,14); - rinfo->nodeOffset = SVAL(p,16); - DEBUG(3,("referral version=%d, size=%d, server_type=%d, flags=0x%x, proximity=%d, ttl=%d, pathOffset=%d, altPathOffset=%d, nodeOffset=%d\n", - version, size, rinfo->server_type, rinfo->referral_flags, - rinfo->proximity, rinfo->ttl, rinfo->pathOffset, - rinfo->altPathOffset, rinfo->nodeOffset)); - - q = (char*)(p + (rinfo->pathOffset)); - //printf("p=%p, q=%p, offset=%d\n", p, q, rinfo->pathOffset); - //printf("hex=0x%x, string=%s\n", q, q); - clistr_pull(cli, rinfo->path, q, - sizeof(rinfo->path), - -1, STR_TERMINATE); - DEBUG(4,("referral path=%s\n", rinfo->path)); - q = (char*)(p + (rinfo->altPathOffset)/sizeof(char)); - if (rinfo->altPathOffset > 0) - clistr_pull(cli, rinfo->altPath, q, - sizeof(rinfo->altPath), - -1, STR_TERMINATE); - DEBUG(4,("referral alt path=%s\n", rinfo->altPath)); - q = (char*)(p + (rinfo->nodeOffset)/sizeof(char)); - if (rinfo->nodeOffset > 0) - clistr_pull(cli, rinfo->node, q, - sizeof(rinfo->node), - -1, STR_TERMINATE); - DEBUG(4,("referral node=%s\n", rinfo->node)); - fstrcpy(rinfo->host, &rinfo->node[1]); - p = strchr_m(&rinfo->host[1],'\\'); - if (!p) { - printf("invalid referral node %s\n", rinfo->node); - return -1; - } - *p = 0; - rinfo->share = talloc_strdup(cli->mem_ctx, p+1); - DEBUG(3,("referral host=%s share=%s\n", - rinfo->host, rinfo->share)); - return size; -} - -#if 0 -int smbcli_select_dfs_referral(struct smbcli_state *cli, dfs_info* dinfo) -{ - return (int)sys_random()%dinfo->number_referrals; -} - -int smbcli_get_dfs_referral(struct smbcli_state *cli,const char *Fname, dfs_info* dinfo) -{ - struct smb_trans2 parms; - int info_level; - char *p; - pstring fname; - int i; - char *rparam=NULL, *rdata=NULL; - int param_len, data_len; - uint16_t setup; - pstring param; - DATA_BLOB trans_param, trans_data; - - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - - pstrcpy(fname,Fname); - - setup = TRANSACT2_GET_DFS_REFERRAL ; - SSVAL(param,0,SMBCLI_DFS_MAX_REFERRAL_LEVEL); /* attribute */ - p = param+2; - p += clistr_push(cli, param+2, fname, -1, - STR_TERMINATE); - - param_len = PTR_DIFF(p, param); - DEBUG(3,("smbcli_get_dfs_referral: sending request\n")); - - trans_param.length = param_len; - trans_param.data = param; - trans_data.length = 0; - trans_data.data = NULL; - - if (!smbcli_send_trans(cli, SMBtrans2, - NULL, /* Name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - &trans_param, 10, /* param, length, max */ - &trans_data, - cli->max_xmit /* data, length, max */ - )) { - return 0; - } - - if (!smbcli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len) && - smbcli_is_dos_error(cli)) { - return 0; - } - //printf("smbcli_get_dfs_referral: received response, rdata=%p, rparam=%p\n", - // rdata, rparam); - - if (smbcli_is_error(cli) || !rdata) - return 0; - - /* parse out some important return info */ - //printf("smbcli_get_dfs_referral: valid response\n"); - p = rdata; - dinfo->path_consumed = SVAL(p,0); - dinfo->number_referrals = SVAL(p,2); - dinfo->referral_flags = SVAL(p,4); - DEBUG(3,("smbcli_get_dfs_referral: path_consumed=%d, # referrals=%d, flags=0x%x\n", - dinfo->path_consumed, dinfo->number_referrals, - dinfo->referral_flags)); - - /* point to the referral bytes */ - p+=8; - for (i=0; i < dinfo->number_referrals; i++) { - p += interpret_referral(cli,info_level,p,&dinfo->referrals[i]); - } - - SAFE_FREE(rdata); - SAFE_FREE(rparam); - - DEBUG(3,("received %d Dfs referrals\n", - dinfo->number_referrals)); - - dinfo->selected_referral = smbcli_select_dfs_referral(cli, dinfo); - DEBUG(3, ("selected Dfs referral %d %s\n", - dinfo->selected_referral, dinfo->referrals[dinfo->selected_referral].node)); - - return(dinfo->number_referrals); -} -#endif - -/* check if the server produced Dfs redirect */ -BOOL smbcli_check_dfs_redirect(struct smbcli_state* c, char* fname, - dfs_info* dinfo) -{ - //printf("check_dfs_redirect: error %s\n", - // smbcli_errstr(c)); - if (smbcli_is_dos_error(c)) { - printf("got dos error\n"); - return False; - - } else { - NTSTATUS status; - - /* Check NT error */ - - status = smbcli_nt_error(c); - //printf("got nt error 0x%x\n", status); - - if (NT_STATUS_V(NT_STATUS_PATH_NOT_COVERED) != NT_STATUS_V(status)) { - return False; - } - } - /* execute trans2 getdfsreferral */ - //printf("check_dfs_redirect: process referral\n"); - //smbcli_get_dfs_referral(c, fname, dinfo); - return True; -} - -int smbcli_dfs_open_connection(struct smbcli_client* cluster, - char* host, char* share, int flags) -{ - int i; - BOOL retry; - struct smbcli_state* c; - - // check if already connected - for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { - if (cluster->cli[i]->in_use && strequal(host, smbcli_state_get_host(cluster->cli[i])) - && strequal(share, smbcli_state_get_share(cluster->cli[i]))) { - DEBUG(3,("smbcli_dfs_open_connection: already connected to \\\\%s\\%s\n", host, share)); - return i; - } - } - // open connection - DEBUG(3,("smbcli_dfs_open_connection: opening \\\\%s\\%s %s@%s\n", - host, share, cluster->username, cluster->workgroup)); - for (i=0; i < DFS_MAX_CLUSTER_SIZE; i++) { - if (!cluster->cli[i]->in_use) { - break; - } - } - if (i >= DFS_MAX_CLUSTER_SIZE) - return -1; - - c = cluster->cli[i]; - if (NT_STATUS_IS_ERR(smbcli_full_connection(NULL, &c, - NULL, host, NULL, 0, - share, "?????", - cluster->username, cluster->workgroup, - cluster->password, flags, - &retry))) - return -1; - smbcli_state_set_sockopt(cluster->cli[i], cluster->sockops); - smbcli_state_set_host(cluster->cli[i], host); - smbcli_state_set_share(cluster->cli[i], share); - cluster->cli[i]->in_use = True; - DEBUG(3,("smbcli_dfs_open_connection: connected \\\\%s\\%s (%d) %s@%s\n", - smbcli_state_get_host(cluster->cli[i]), smbcli_state_get_share(cluster->cli[i]), i, - cluster->username, cluster->workgroup)); - - return i; -} - -/********************************************************************** - Parse the pathname of the form \hostname\service\reqpath - into the dfs_path structure - **********************************************************************/ - -BOOL smbcli_parse_dfs_path(char* pathname, struct dfs_path* pdp) -{ - pstring pathname_local; - char* p,*temp; - - pstrcpy(pathname_local,pathname); - p = temp = pathname_local; - - ZERO_STRUCTP(pdp); - - trim_string(temp,"\\","\\"); - DEBUG(10,("temp in smbcli_parse_dfs_path: .%s. after trimming \\'s\n",temp)); - - /* now tokenize */ - /* parse out hostname */ - p = strchr(temp,'\\'); - if(p == NULL) - return False; - *p = '\0'; - pstrcpy(pdp->hostname,temp); - DEBUG(10,("hostname: %s\n",pdp->hostname)); - - /* parse out servicename */ - temp = p+1; - p = strchr(temp,'\\'); - if(p == NULL) { - pstrcpy(pdp->servicename,temp); - pdp->reqpath[0] = '\0'; - return True; - } - *p = '\0'; - pstrcpy(pdp->servicename,temp); - DEBUG(10,("servicename: %s\n",pdp->servicename)); - - /* rest is reqpath */ - pstrcpy(pdp->reqpath, p+1); - - DEBUG(10,("rest of the path: %s\n",pdp->reqpath)); - return True; -} - -char* rebuild_filename(char *referral_fname, struct smbcli_state* c, - char* fname, int path_consumed) -{ - const char *template = "\\\\%s\\%s\\%s"; - struct dfs_path dp; - - // TODO: handle consumed length - DEBUG(3,("rebuild_filename: %s, %d consumed of %d\n", - fname, path_consumed, strlen(fname))); - if (smbcli_parse_dfs_path(fname, &dp)) { - DEBUG(3,("rebuild_filename: reqpath=%s\n", - dp.reqpath)); - asprintf(&referral_fname, - template, smbcli_state_get_host(c), - smbcli_state_get_share(c), dp.reqpath); - } - else - return NULL; - DEBUG(3,("rebuild_filename: %s -> %s\n", fname, referral_fname)); - return referral_fname; -} - -/**************************************************************************** - Open a file (allowing for Dfs referral). -****************************************************************************/ - -int smbcli_dfs_open(struct smbcli_client* cluster, int *server, - char *fname_src, int flags, int share_mode) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - int fnum; - - DEBUG(3,("smbcli_dfs_open: open %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if ((fnum = smbcli_open(cluster->cli[*server], fname_src, flags, share_mode)) < 0) { - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_open: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_open: Dfs open %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - fnum = smbcli_open(cluster->cli[*server], fname_src, flags, share_mode); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_open: open of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - return -1; - } - } - DEBUG(3,("smbcli_dfs_open: open %s fnum=%d\n", - fname_src, fnum)); - return fnum; -} - -/**************************************************************************** - Delete a file (allowing for Dfs referral). -****************************************************************************/ - -NTSTATUS smbcli_nt_unlink(struct smbcli_client* cluster, int *server, - char *fname_src, uint16_t FileAttributes) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - struct smb_unlink parms; - - DEBUG(3,("smbcli_nt_unlink: delete %s on server %s(%d), attributes=0x%x\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server, - FileAttributes)); - cluster->cli[*server]->dfs_referral = *server; - parms.in.pattern = fname_src; - parms.in.dirtype = FileAttributes; - if (NT_STATUS_IS_ERR(smbcli_raw_unlink(cluster->cli[*server], &parms))) { - printf("smbcli_nt_unlink: delete of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_nt_unlink: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return NT_STATUS_INTERNAL_ERROR; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return NT_STATUS_INTERNAL_ERROR; - fname_src = referral_fname; - DEBUG(3,("smbcli_nt_unlink: Dfs delete %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_raw_unlink(cluster->cli[*server], &parms); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_nt_unlink: delete of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - } - } - return smbcli_nt_error(cluster->cli[*server]); -} - -/**************************************************************************** - Rename a file (allowing for Dfs referral). -****************************************************************************/ - -BOOL smbcli_dfs_rename(struct smbcli_client* cluster, int *server, - char *fname_src, char *fname_dst) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - - DEBUG(3,("smbcli_dfs_rename: rename %s to %s on server %s(%d)\n", - fname_src, fname_dst, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if (!smbcli_rename(cluster->cli[*server], fname_src, fname_dst)) { - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_rename: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_rename: Dfs rename %s to %s on server %s(%d)\n", - fname_src, fname_dst, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_rename(cluster->cli[*server], fname_src, fname_dst); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_rename: rename of %s to %s failed (%s)\n", - fname_src, fname_dst, smbcli_errstr(cluster->cli[*server])); - return False; - } - } - return True; -} - -/**************************************************************************** - Make directory (allowing for Dfs referral). -****************************************************************************/ - -BOOL smbcli_dfs_mkdir(struct smbcli_client* cluster, int *server, - char *fname_src) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - - DEBUG(3,("smbcli_dfs_mkdir: mkdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if (!smbcli_mkdir(cluster->cli[*server], fname_src)) { - printf("smbcli_dfs_mkdir: mkdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_mkdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_mkdir: Dfs mkdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_mkdir(cluster->cli[*server], fname_src); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_mkdir: mkdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - return False; - } - } - return True; -} - -/**************************************************************************** - Remove directory (allowing for Dfs referral). -****************************************************************************/ - -BOOL smbcli_dfs_rmdir(struct smbcli_client* cluster, int *server, - char *fname_src) -{ - int referral_number; - dfs_info dinfo; - char *referral_fname; - - DEBUG(3,("smbcli_dfs_rmdir: rmdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - cluster->cli[*server]->dfs_referral = *server; - if (!smbcli_rmdir(cluster->cli[*server], fname_src)) { - printf("smbcli_dfs_rmdir: rmdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - if (smbcli_check_dfs_redirect(cluster->cli[*server], fname_src, &dinfo)) { - // choose referral, check if already connected, open if not - referral_number = dinfo.selected_referral; - DEBUG(3,("smbcli_dfs_rmdir: redirecting to %s\n", dinfo.referrals[referral_number].node)); - cluster->cli[*server]->dfs_referral = smbcli_dfs_open_connection(cluster, - dinfo.referrals[referral_number].host, - dinfo.referrals[referral_number].share, - cluster->connection_flags); - *server = cluster->cli[*server]->dfs_referral; - if (server < 0) - return False; - // rebuild file name and retry operation. - if (rebuild_filename(referral_fname, cluster->cli[*server], fname_src, dinfo.path_consumed) == NULL) - return False; - fname_src = referral_fname; - DEBUG(3,("smbcli_dfs_rmdir: Dfs rmdir %s on server %s(%d)\n", - fname_src, smbcli_state_get_host(cluster->cli[*server]), *server)); - smbcli_rmdir(cluster->cli[*server], fname_src); - } - if (smbcli_is_error(cluster->cli[*server])) { - printf("smbcli_dfs_rmdir: rmdir of %s failed (%s)\n", - fname_src, smbcli_errstr(cluster->cli[*server])); - return False; - } - } - return True; -} diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index e8b97f324d..8b05b98e0e 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -20,11 +20,11 @@ */ #include "includes.h" -#include "client.h" +#include "clilist.h" #include "libcli/raw/libcliraw.h" struct search_private { - struct file_info *dirlist; + struct clilist_file_info *dirlist; TALLOC_CTX *mem_ctx; int dirlist_len; int ff_searchcount; /* total received in 1 server trip */ @@ -40,9 +40,9 @@ struct search_private { ****************************************************************************/ static BOOL interpret_long_filename(enum smb_search_level level, union smb_search_data *info, - struct file_info *finfo) + struct clilist_file_info *finfo) { - struct file_info finfo2; + struct clilist_file_info finfo2; if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); @@ -50,23 +50,17 @@ static BOOL interpret_long_filename(enum smb_search_level level, switch (level) { case RAW_SEARCH_STANDARD: finfo->size = info->standard.size; - finfo->ctime = info->standard.create_time; - finfo->atime = info->standard.access_time; finfo->mtime = info->standard.write_time; - finfo->mode = info->standard.attrib; + finfo->attrib = info->standard.attrib; finfo->name = info->standard.name.s; + finfo->short_name = info->standard.name.s; break; case RAW_SEARCH_BOTH_DIRECTORY_INFO: finfo->size = info->both_directory_info.size; - finfo->ctime = nt_time_to_unix(info->both_directory_info.create_time); - finfo->atime = nt_time_to_unix(info->both_directory_info.access_time); finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time); - finfo->mode = info->both_directory_info.attrib; /* 32 bit->16 bit attrib */ - if (info->both_directory_info.short_name.s) { - strncpy(finfo->short_name, info->both_directory_info.short_name.s, - sizeof(finfo->short_name)-1); - } + finfo->attrib = info->both_directory_info.attrib; + finfo->short_name = info->both_directory_info.short_name.s; finfo->name = info->both_directory_info.name.s; break; @@ -82,18 +76,18 @@ static BOOL interpret_long_filename(enum smb_search_level level, static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; - struct file_info *tdl; + struct clilist_file_info *tdl; /* add file info to the dirlist pool */ tdl = talloc_realloc(state, state->dirlist, - state->dirlist_len + sizeof(struct file_info)); + state->dirlist_len + sizeof(struct clilist_file_info)); if (!tdl) { return False; } state->dirlist = tdl; - state->dirlist_len += sizeof(struct file_info); + state->dirlist_len += sizeof(struct clilist_file_info); interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]); @@ -106,7 +100,7 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file) int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, enum smb_search_level level, - void (*fn)(struct file_info *, const char *, void *), + void (*fn)(struct clilist_file_info *, const char *, void *), void *caller_state) { union smb_search_first first_parms; @@ -209,19 +203,18 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu ****************************************************************************/ static BOOL interpret_short_filename(int level, union smb_search_data *info, - struct file_info *finfo) + struct clilist_file_info *finfo) { - struct file_info finfo2; + struct clilist_file_info finfo2; if (!finfo) finfo = &finfo2; ZERO_STRUCTP(finfo); - finfo->ctime = info->search.write_time; - finfo->atime = info->search.write_time; finfo->mtime = info->search.write_time; finfo->size = info->search.size; - finfo->mode = info->search.attrib; + finfo->attrib = info->search.attrib; finfo->name = info->search.name; + finfo->short_name = info->search.name; return True; } @@ -229,18 +222,18 @@ static BOOL interpret_short_filename(int level, static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) { struct search_private *state = (struct search_private*) private; - struct file_info *tdl; + struct clilist_file_info *tdl; /* add file info to the dirlist pool */ tdl = talloc_realloc(state, state->dirlist, - state->dirlist_len + sizeof(struct file_info)); + state->dirlist_len + sizeof(struct clilist_file_info)); if (!tdl) { return False; } state->dirlist = tdl; - state->dirlist_len += sizeof(struct file_info); + state->dirlist_len += sizeof(struct clilist_file_info); interpret_short_filename(state->info_level, file, &state->dirlist[state->total_received]); @@ -252,7 +245,7 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file) } int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, - void (*fn)(struct file_info *, const char *, void *), + void (*fn)(struct clilist_file_info *, const char *, void *), void *caller_state) { union smb_search_first first_parms; @@ -338,7 +331,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu ****************************************************************************/ int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute, - void (*fn)(struct file_info *, const char *, void *), void *state) + void (*fn)(struct clilist_file_info *, const char *, void *), void *state) { if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) return smbcli_list_old(tree, Mask, attribute, fn, state); diff --git a/source4/torture/basic/dir.c b/source4/torture/basic/dir.c index 0f962e6cf1..1394ef5b5b 100644 --- a/source4/torture/basic/dir.c +++ b/source4/torture/basic/dir.c @@ -23,7 +23,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_security.h" -static void list_fn(struct file_info *finfo, const char *name, void *state) +static void list_fn(struct clilist_file_info *finfo, const char *name, void *state) { } diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c index c0890118c3..ee15f92d80 100644 --- a/source4/torture/masktest.c +++ b/source4/torture/masktest.c @@ -20,7 +20,7 @@ #include "includes.h" #include "dynconfig.h" -#include "client.h" +#include "clilist.h" #include "libcli/raw/libcliraw.h" #include "system/time.h" @@ -98,7 +98,7 @@ static struct { } last_hit; static BOOL f_info_hit; -static void listfn(struct file_info *f, const char *s, void *state) +static void listfn(struct clilist_file_info *f, const char *s, void *state) { if (strcmp(f->name,".") == 0) { resultp[0] = '+'; diff --git a/source4/torture/torture.c b/source4/torture/torture.c index ca8c3342b6..43f276e0c2 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -20,7 +20,7 @@ #include "includes.h" #include "dynconfig.h" -#include "client.h" +#include "clilist.h" #include "lib/cmdline/popt_common.h" #include "libcli/raw/libcliraw.h" #include "system/time.h" @@ -37,7 +37,6 @@ static int procnum; /* records process count number when forking */ static struct smbcli_state *current_cli; static BOOL use_oplocks; static BOOL use_level_II_oplocks; -static BOOL use_kerberos; BOOL torture_showall = False; @@ -99,9 +98,6 @@ BOOL torture_open_connection_share(struct smbcli_state **c, const char *userdomain = lp_parm_string(-1, "torture", "userdomain"); const char *password = lp_parm_string(-1, "torture", "password"); - if (use_kerberos) - flags |= SMBCLI_FULL_CONNECTION_USE_KERBEROS; - status = smbcli_full_connection(NULL, c, lp_netbios_name(), hostname, NULL, -- cgit