Unix SMB/Netbios implementation.
Version 1.9.
Tar Extensions
- Copyright (C) Ricky Poulten 1995-1997
+ Copyright (C) Ricky Poulten 1995-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
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) are Copyright (C) 1998 by CISRA and are
+ made available under the terms of the GPL as listed above:
+
+ 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 :-)
+
+*/
#include "includes.h"
#include "clitar.h"
+#include <regex.h>
extern BOOL recurse;
BOOL tar_reset=False;
/* Include / exclude mode (true=include, false=exclude) */
BOOL tar_excl=True;
+/* Dump files with System attribute */
+BOOL tar_system=False;
+/* Dump files with Hidden attribute */
+BOOL tar_hidden=True;
+/* Be noisy - make a catalogue */
+BOOL tar_noisy=True;
+
char tar_type='\0';
static char **cliplist=NULL;
static int clipn=0;
int blocksize=20;
int tarhandle;
-static void writetarheader();
-static void do_atar();
-static void do_tar();
-static void oct_it();
-static void fixtarname();
-static int dotarbuf();
-static void dozerobuf();
-static void dotareof();
-static void initarbuf();
-static int do_setrattr();
-
-/* restore functions */
-static long readtarheader();
-static long unoct();
-static void do_tarput();
-static void unfixtarname();
+static void writetarheader(int f, char *aname, int size, time_t mtime,
+ char *amode, unsigned char ftype);
+
+/* Forward references. */
+static void fixtarname(char *tptr, char *fp, int l);
+static int dotarbuf(int f, char *b, int n);
+static void oct_it (long value, int ndgs, char *p);
+static long unoct(char *p, int ndgs);
+static void unfixtarname(char *tptr, char *fp, int l);
/*
* tar specific utitlities
Write a tar header to buffer
****************************************************************************/
static void writetarheader(int f, char *aname, int size, time_t mtime,
- char *amode)
+ char *amode, unsigned char ftype)
{
union hblock hb;
int i, chk, l;
char *jp;
+ DEBUG(5, ("WriteTarHdr, Type = %c, Name = %s\n", ftype, aname));
+
memset(hb.dummy, 0, sizeof(hb.dummy));
l=strlen(aname);
- if (l >= NAMSIZ)
- {
- DEBUG(0, ("tar file %s name length exceeds NAMSIZ\n", aname));
- }
+ if (l >= 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+1, 0, " 0 \0", 'L');
+ memset(b, 0, l+TBLOCK+100);
+ fixtarname(b, aname, l+1);
+ i = strlen(b)+1;
+ dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
+ free(b);
+ }
/* use l + 1 to do the null too */
fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1);
oct_it((long) size, 13, hb.dbuf.size);
oct_it((long) mtime, 13, hb.dbuf.mtime);
memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
- hb.dbuf.linkflag='0';
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++);
unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
strlen(hb->dbuf.name) + 1);
-/* can't handle links at present */
- if (hb->dbuf.linkflag != '0') {
+/* 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 {
- DEBUG(0, ("this tar file appears to contain some kind of link - ignoring\n"));
- return -2;
+ 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;
+ }
}
}
}
/****************************************************************************
-Write a zeros to buffer / tape
+Write zeros to buffer / tape
****************************************************************************/
static void dozerobuf(int f, int n)
{
if (n+tp >= tbufsiz)
{
memset(tarbuf+tp, 0, tbufsiz-tp);
+
write(f, tarbuf, tbufsiz);
memset(tarbuf, 0, (tp+=n-tbufsiz));
}
/****************************************************************************
Malloc tape buffer
****************************************************************************/
-static void initarbuf()
+static void initarbuf(void)
{
/* initialize tar buffer */
tbufsiz=blocksize*TBLOCK;
- tarbuf=malloc(tbufsiz);
+ 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;
* to lovely unix /'s :-} */
*tptr++='.';
-#ifdef KANJI
+
while (l > 0) {
- if (is_shift_jis (*fp)) {
- *tptr++ = *fp++;
- *tptr++ = *fp++;
- l -= 2;
- } else if (is_kana (*fp)) {
- *tptr++ = *fp++;
- l--;
+ int skip;
+ if((skip = skip_multibyte_char( *fp)) != 0) {
+ if (skip == 2) {
+ *tptr++ = *fp++;
+ *tptr++ = *fp++;
+ l -= 2;
+ } else if (skip == 1) {
+ *tptr++ = *fp++;
+ l--;
+ }
} else if (*fp == '\\') {
*tptr++ = '/';
fp++;
l--;
}
}
-#else
- while (l--) { *tptr=(*fp == '\\') ? '/' : *fp; tptr++; fp++; }
-#endif
}
/****************************************************************************
Convert from decimal to octal string
****************************************************************************/
-static void oct_it (register long value, register int ndgs, register char *p)
+static void oct_it (long value, int ndgs, char *p)
{
/* Converts long to octal string, pads with leading zeros */
/*
* general smb utility functions
*/
+/**********************************************************************
+do_setrtime, set time on a file or dir ...
+**********************************************************************/
+
+static int do_setrtime(char *fname, int mtime)
+{
+ char *inbuf, *outbuf, *p;
+ char *name;
+
+ name = (char *)malloc(strlen(fname) + 1 + 1);
+ if (name == NULL) {
+
+ DEBUG(0, ("Failed to allocate space while setting time on file: %s", fname));
+ return False;
+
+ }
+
+ strcpy(name, fname);
+ strcpy(fname, "\\");
+ strcat(fname, name);
+
+ inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+
+ if (!inbuf || !outbuf) {
+
+ DEBUG(0, ("Could not allocate memory for inbuf or outbuf while changing time on: %s\n", fname));
+ return False;
+
+ }
+
+ memset(outbuf, 0, smb_size);
+ set_message(outbuf, 8, 4 + strlen(fname), True);
+ CVAL(outbuf, smb_com) = SMBsetatr;
+ SSVAL(outbuf, smb_tid, cnum);
+ cli_setup_pkt(outbuf);
+
+ SSVAL(outbuf, smb_vwv0, 0);
+ put_dos_date3(outbuf, smb_vwv1, mtime);
+
+ p = smb_buf(outbuf);
+ *p++ = 4;
+ strcpy(p, fname);
+ p+= (strlen(fname)+1);
+
+ *p++ = 4;
+ *p++ = 0;
+
+ send_smb(Client, outbuf);
+ client_receive_smb(Client, inbuf, CLIENT_TIMEOUT);
+
+ if (CVAL(inbuf,smb_rcls) != 0)
+ {
+ DEBUG(0,("%s setting attributes on file %s\n",
+ smb_errstr(inbuf), fname));
+ free(inbuf);free(outbuf);
+ return(False);
+ }
+
+ free(inbuf);free(outbuf);
+ return(True);
+
+}
+
/****************************************************************************
Set DOS file attributes
***************************************************************************/
set_message(outbuf,0,2 + strlen(fname),True);
CVAL(outbuf,smb_com) = SMBgetatr;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
p = smb_buf(outbuf);
*p++ = 4;
*p++ = 0;
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
DEBUG(5,("getatr: %s\n",smb_errstr(inbuf)));
set_message(outbuf,8,4 + strlen(fname),True);
CVAL(outbuf,smb_com) = SMBsetatr;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,attr);
-
+
p = smb_buf(outbuf);
*p++ = 4;
strcpy(p,fname);
*p++ = 0;
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
char *p;
/* *must* be called with buffer ready malloc'ed */
/* open remote file */
-
+
memset(outbuf,0,smb_size);
set_message(outbuf,3,2 + strlen(finfo.name),True);
CVAL(outbuf,smb_com) = SMBcreate;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,finfo.mode);
put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
strcpy(p,finfo.name);
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
set_message(outbuf,5,n + 3, False);
CVAL(outbuf,smb_com) = SMBwrite;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,fnum);
SSVAL(outbuf,smb_vwv1,n);
SSVAL(smb_buf(outbuf),1,n);
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
set_message(outbuf,3,0,True);
CVAL(outbuf,smb_com) = SMBclose;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,fnum);
put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
finfo.mtime));
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
set_message(outbuf,0,4 + strlen(fname),True);
CVAL(outbuf,smb_com) = SMBchkpth;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
p = smb_buf(outbuf);
*p++ = 4;
strcpy(p,fname);
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
DEBUG(5,("smbchkpath: %s\n",smb_errstr(inbuf)));
CVAL(outbuf,smb_com) = SMBmkdir;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
p = smb_buf(outbuf);
*p++ = 4;
strcpy(p,fname);
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
pstring partpath, ffname;
char *p=fname, *basehack;
+ DEBUG(5, ( "Ensurepath called with: %s\n", fname));
+
*partpath = 0;
/* fname copied to ffname so can strtok */
{
int fnum;
uint32 nread=0;
- char *p;
+ char *p, ftype;
char *inbuf,*outbuf;
file_info finfo;
BOOL close_done = False;
struct timeval tp_start;
GetTimeOfDay(&tp_start);
+ ftype = '0'; /* An ordinary file ... */
+
if (finfo1)
finfo = *finfo1;
else
CVAL(outbuf,smb_com) = SMBopenX;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,0xFF);
SSVAL(outbuf,smb_vwv2,1);
}
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
if (CVAL(inbuf,smb_rcls) == ERRSRV &&
SVAL(inbuf,smb_err) == ERRnoresource &&
- reopen_connection(inbuf,outbuf))
+ cli_reopen_connection(inbuf,outbuf))
{
do_atar(rname,lname,finfo1);
free(inbuf);free(outbuf);
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
{
if (SVAL(inbuf,smb_vwv0) == SMBreadX)
datalen = 0;
}
- DEBUG(1,("getting file %s of size %d bytes as a tar file %s",
+ DEBUG(2,("getting file %s of size %d bytes as a tar file %s",
finfo.name,
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");
+ writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
while (nread < finfo.size && !close_done)
{
set_message(outbuf,10,0,True);
CVAL(outbuf,smb_com) = SMBreadX;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
if (close_done)
{
}
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
set_message(outbuf,8,0,True);
CVAL(outbuf,smb_com) = SMBreadbraw;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,fnum);
SIVAL(outbuf,smb_vwv1,nread);
SSVAL(outbuf,smb_vwv3,MIN(finfo.size-nread,readbraw_size));
set_message(outbuf,5,0,True);
CVAL(outbuf,smb_com) = SMBread;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,fnum);
SSVAL(outbuf,smb_vwv1,MIN(max_xmit-200,finfo.size - nread));
SSVAL(outbuf,smb_vwv4,finfo.size - nread);
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (CVAL(inbuf,smb_rcls) != 0)
{
* write out in 512 byte intervals */
if (dotarbuf(tarhandle,dataptr,datalen) != datalen)
{
- DEBUG(0,("Error writing local file\n"));
+ DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
break;
}
{
DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", finfo.size, nread));
if (padit(inbuf, BUFFER_SIZE, finfo.size - nread))
- DEBUG(0,("Error writing local file\n"));
+ DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
}
/* round tar file to nearest block */
set_message(outbuf,3,0,True);
CVAL(outbuf,smb_com) = SMBclose;
SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
+ cli_setup_pkt(outbuf);
SSVAL(outbuf,smb_vwv0,fnum);
SIVALS(outbuf,smb_vwv1,-1);
send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
if (!ignore_close_error && CVAL(inbuf,smb_rcls) != 0)
{
get_total_size += finfo.size;
/* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
- DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
+ DEBUG(2,("(%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))));
+ if (tar_noisy)
+ {
+ printf("%10d (%7.1f kb/s) %s\n",
+ finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
+ finfo.name);
+ }
+
}
free(inbuf);free(outbuf);
{
pstring rname;
- if (strequal(finfo->name,".") || strequal(finfo->name,".."))
+ if (strequal(finfo->name,".."))
return;
/* Is it on the exclude list ? */
strcat(cur_dir,finfo->name);
strcat(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");
+ writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
+ ntarf++; /* Make sure we have a file on there */
strcpy(mtar_mask,cur_dir);
strcat(mtar_mask,"*");
-
- do_dir((char *)inbuf,(char *)outbuf,mtar_mask,attribute,do_tar,recurse);
- strcpy(cur_dir,saved_curdir);
+ /* do_dir((char *)inbuf,(char *)outbuf,mtar_mask,attribute,do_tar,recurse,True); */
+ strcpy(cur_dir,saved_curdir);
free(inbuf);free(outbuf);
}
else
if (*fp == '.') fp++;
if (*fp == '\\' || *fp == '/') fp++;
-#ifdef KANJI
while (l > 0) {
- if (is_shift_jis (*fp)) {
- *tptr++ = *fp++;
- *tptr++ = *fp++;
- l -= 2;
- } else if (is_kana (*fp)) {
- *tptr++ = *fp++;
- l--;
+ int skip;
+ if(( skip = skip_multibyte_char( *fp )) != 0) {
+ if (skip == 2) {
+ *tptr++ = *fp++;
+ *tptr++ = *fp++;
+ l -= 2;
+ } else if (skip == 1) {
+ *tptr++ = *fp++;
+ l--;
+ }
} else if (*fp == '/') {
*tptr++ = '\\';
fp++;
l--;
}
}
-#else
- while (l--) { *tptr=(*fp == '/') ? '\\' : *fp; tptr++; fp++; }
-#endif
}
-static void do_tarput()
+static void do_tarput(void)
{
file_info finfo;
int nread=0, bufread;
- char *inbuf,*outbuf;
+ char *inbuf,*outbuf, *longname = NULL;
int fsize=0;
int fnum;
struct timeval tp_start;
do {
if (!fsize)
{
- switch (readtarheader((union hblock *) bufferp, &finfo, cur_dir))
- {
- case -2: /* something dodgy but not fatal about this */
- DEBUG(0, ("skipping %s...\n", finfo.name));
- bufferp+=TBLOCK; /* header - like a link */
- continue;
- case -1:
- DEBUG(0, ("abandoning restore\n"));
- free(inbuf); free(outbuf);
- return;
- case 0: /* chksum is zero - we assume that one all zero
- *header block will do for eof */
- DEBUG(0,
- ("total of %d tar files restored to share\n", ntarf));
- free(inbuf); free(outbuf);
- return;
- default:
- break;
- }
+ int next_header = 1; /* Want at least one header */
+ while (next_header)
+ {
+ if (bufferp >= endofbuffer) {
+
+ bufread = read(tarhandle, tarbuf, tbufsiz);
+ bufferp = tarbuf;
+
+ }
+ next_header = 0; /* Don't want the next one ... */
+ switch (readtarheader((union hblock *) bufferp, &finfo, cur_dir))
+ {
+ case -2: /* something dodgy but not fatal about this */
+ DEBUG(0, ("skipping %s...\n", finfo.name));
+ bufferp+=TBLOCK; /* header - like a link */
+ continue;
+ case -1:
+ DEBUG(0, ("abandoning restore, -1 from readtarheader\n"));
+ free(inbuf); free(outbuf);
+ return;
+ case 0: /* chksum is zero - we assume that one all zero
+ *header block will do for eof */
+ DEBUG(0,
+ ("total of %d tar files restored to share\n", ntarf));
+ free(inbuf); free(outbuf);
+ return;
+ default:
+ break;
+ }
+
+ /* If we have a longname left from the last time through,
+ copy it into finfo.name and free it.
+
+ The size of a pstring is the limiting factor on filenames
+ and directory names now. The total pathname length must be
+ less than sizeof(pstring) - 1, which is currently 1023. */
+
+ if (longname != NULL) {
+
+ strncpy(finfo.name, longname, sizeof(pstring) - 1);
+ free(longname);
+ longname = NULL;
+
+ }
+
+ /* Check if a long-link. We do this before the clip checking
+ because clip-checking should clip on real name - RJS */
+
+ if (((union hblock *)bufferp) -> dbuf.linkflag == 'L') {
+ /* Skip this header, but pick up length, get the name and
+ fix the name and skip the name. Hmmm, what about end of
+ buffer??? */
+
+ longname = malloc(finfo.size + strlen(cur_dir) + 1);
+ if (longname == NULL) {
+
+ DEBUG(0, ("could not allocate buffer of size %d for longname\n",
+ finfo.size + strlen(cur_dir) + 1)
+ );
+ free(inbuf); free(outbuf);
+ return;
+ }
+
+ bufferp += TBLOCK; /* Skip that longlink header */
+
+ /* This needs restructuring ... */
+
+ if (bufferp >= endofbuffer) {
+
+ bufread = read(tarhandle, tarbuf, tbufsiz);
+
+ bufferp = tarbuf;
+
+ }
+
+ strncpy(longname, cur_dir, strlen(cur_dir));
+ unfixtarname(longname+strlen(cur_dir), bufferp, finfo.size);
+
+ /* Next rounds up to next TBLOCK and takes care of us being right
+ on a TBLOCK boundary */
+
+ bufferp += (((finfo.size - 1)/TBLOCK)+1)*TBLOCK;
+ next_header = 1; /* Force read of next header */
+
+ }
+ }
tskip=clipn
&& (clipfind(cliplist, clipn, finfo.name) ^ tar_excl);
if (tskip) {
}
}
+ DEBUG(5, ("do_tarput: File is: %s\n", finfo.name));
+
if (finfo.mode & aDIR)
{
- if (!smbchkpath(finfo.name, inbuf, outbuf)
- && !smbmkdir(finfo.name, inbuf, outbuf))
+ if (!ensurepath(finfo.name, inbuf, outbuf))
+/* if (!smbchkpath(finfo.name, inbuf, outbuf)
+ && !smbmkdir(finfo.name, inbuf, outbuf))*/
{
- DEBUG(0, ("abandoning restore\n"));
+ DEBUG(0, ("abandoning restore, problems ensuring path\n"));
free(inbuf); free(outbuf);
return;
}
else
{
+ /* Now we update the creation date ... */
+
+ DEBUG(5, ("Updating creation date on %s\n", finfo.name));
+
+ if (!do_setrtime(finfo.name, finfo.mtime)) {
+
+ DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
+ return;
+
+ }
+
+ ntarf++;
bufferp+=TBLOCK;
continue;
}
return;
}
- DEBUG(0,("restore tar file %s of size %d bytes\n",
+ DEBUG(0 ,("restore tar file %s of size %d bytes\n",
finfo.name,finfo.size));
+ if (!finfo.size) {
+ if (!smbshut(finfo, fnum, inbuf, outbuf)){
+ DEBUG(0, ("Error closing remote file of length 0: %s\n", finfo.name));
+ free(inbuf);free(outbuf);
+ return;
+ }
+ }
+
nread=0;
if ((bufferp+=TBLOCK) >= endofbuffer) break;
} /* if (!fsize) */
bufferp+=minichunk; nread+=minichunk;
chunk-=minichunk;
}
-
+
if (nread>=fsize)
{
if (!smbshut(finfo, fnum, inbuf, outbuf))
/****************************************************************************
Blocksize command
***************************************************************************/
-void cmd_block(void)
+void cmd_block(char *dum_in, char *dum_out)
{
fstring buf;
int block;
}
blocksize=block;
- DEBUG(1,("blocksize is now %d\n", blocksize));
+ DEBUG(2,("blocksize is now %d\n", blocksize));
}
/****************************************************************************
command to set incremental / reset mode
***************************************************************************/
-void cmd_tarmode(void)
+void cmd_tarmode(char *dum_in, char *dum_out)
{
fstring buf;
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\n",
+ DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
tar_inc ? "incremental" : "full",
- tar_reset ? "reset" : "noreset"));
+ tar_system ? "system" : "nosystem",
+ tar_hidden ? "hidden" : "nohidden",
+ tar_reset ? "reset" : "noreset",
+ tar_noisy ? "verbose" : "quiet"));
+
}
/****************************************************************************
Feeble attrib command
***************************************************************************/
-void cmd_setmode(void)
+void cmd_setmode(char *dum_in, char *dum_out)
{
char *q;
fstring buf;
return;
}
- DEBUG(1, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
+ DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
(void) do_setrattr(fname, attra[ATTRSET], ATTRSET);
(void) do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
}
strcpy(cur_dir, tarmac);
*(strrchr(cur_dir, '\\')+1)='\0';
- do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse);
+ do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse, True);
strcpy(cur_dir,saved_dir);
} else {
strcpy(tarmac, cur_dir);
strcat(tarmac, cliplist[i]);
- do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse);
+ do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse, True);
}
}
} else {
pstring mask;
strcpy(mask,cur_dir);
strcat(mask,"\\*");
- do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_tar,recurse);
+ do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_tar,recurse, True);
}
if (ntarf) dotareof(tarhandle);
tar_excl=tar_clipfl!='X';
if (Optind+1<argc) {
+ 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);
+ tmplist[clipcount] = tmpstr;
+ DEBUG(5, ("Processed an item, %s\n", tmpstr));
+
+ DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));
+ }
+ cliplist = tmplist;
}
if (Optind>=argc || !strcmp(argv[Optind], "-")) {
/* Sets tar handle to either 0 or 1, as appropriate */
if ((tar_type=='x' && (tarhandle = open(argv[Optind], O_RDONLY)) == -1)
|| (tar_type=='c' && (tarhandle=creat(argv[Optind], 0644)) < 0))
{
- DEBUG(0,("Error opening local file %s\n",argv[Optind]));
+ DEBUG(0,("Error opening local file %s - %s\n",
+ argv[Optind], strerror(errno)));
return(0);
}
}