/*
- Unix SMB/Netbios implementation.
- Version 1.9.
+ Unix SMB/CIFS implementation.
Tar Extensions
Copyright (C) Ricky Poulten 1995-1998
Copyright (C) Richard Sharpe 1998
#include "includes.h"
#include "clitar.h"
+#include "../client/client_proto.h"
static int clipfind(char **aret, int ret, char *tok);
struct file_info_struct
{
- size_t size;
+ SMB_BIG_UINT size;
uint16 mode;
- int uid;
- int gid;
+ uid_t uid;
+ gid_t gid;
/* These times are normally kept in GMT */
time_t mtime;
time_t atime;
} stack;
-stack dir_stack = {NULL, 0}; /* Want an empty stack */
-
#define SEPARATORS " \t\n\r"
extern struct cli_state *cli;
static int tp, ntarf, tbufsiz;
static double ttarf;
/* Incremental mode */
-BOOL tar_inc=False;
+static BOOL tar_inc=False;
/* Reset archive bit */
-BOOL tar_reset=False;
+static BOOL tar_reset=False;
/* Include / exclude mode (true=include, false=exclude) */
-BOOL tar_excl=True;
+static BOOL tar_excl=True;
/* use regular expressions for search on file names */
-BOOL tar_re_search=False;
+static BOOL tar_re_search=False;
#ifdef HAVE_REGEX_H
regex_t *preg;
#endif
/* Do not dump anything, just calculate sizes */
-BOOL dry_run=False;
+static BOOL dry_run=False;
/* Dump files with System attribute */
-BOOL tar_system=True;
+static BOOL tar_system=True;
/* Dump files with Hidden attribute */
-BOOL tar_hidden=True;
+static BOOL tar_hidden=True;
/* Be noisy - make a catalogue */
-BOOL tar_noisy=True;
-BOOL tar_real_noisy=False; /* Don't want to be really noisy by default */
+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;
extern int get_total_time_ms;
extern int get_total_size;
-int blocksize=20;
-int tarhandle;
+static int blocksize=20;
+static int tarhandle;
-static void writetarheader(int f, char *aname, int size, time_t mtime,
- char *amode, unsigned char ftype);
+static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
+ const char *amode, unsigned char ftype);
static void do_atar(char *rname,char *lname,file_info *finfo1);
static void do_tar(file_info *finfo);
-static void oct_it(long value, int ndgs, char *p);
-static void fixtarname(char *tptr, char *fp, int l);
+static void oct_it(SMB_BIG_UINT 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);
/****************************************************************************
Write a tar header to buffer
****************************************************************************/
-static void writetarheader(int f, char *aname, int size, time_t mtime,
- char *amode, unsigned char ftype)
+static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
+ const char *amode, unsigned char ftype)
{
union hblock hb;
int i, chk, l;
char *jp;
- DEBUG(5, ("WriteTarHdr, Type = %c, Size= %i, Name = %s\n", ftype, size, aname));
+ DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname));
memset(hb.dummy, 0, sizeof(hb.dummy));
fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1);
if (lowercase)
- strlower(hb.dbuf.name);
+ strlower_m(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(0L, 8, hb.dbuf.uid);
- oct_it(0L, 8, hb.dbuf.gid);
- oct_it((long) size, 13, hb.dbuf.size);
- oct_it((long) mtime, 13, hb.dbuf.mtime);
+ safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
+ oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
+ oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
+ oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
+ if (size > (SMB_BIG_UINT)077777777777LL) {
+
+ /* This is a non-POSIX compatible extention to store files
+ greater than 8GB. */
+
+ memset(hb.dbuf.size, 0, 4);
+ hb.dbuf.size[0]=128;
+ for (i = 8, jp=(char*)&size; i; i--)
+ hb.dbuf.size[i+3] = *(jp++);
+ }
+ oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
memset(hb.dbuf.linkname, 0, NAMSIZ);
hb.dbuf.linkflag=ftype;
for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) chk+=(0xFF & *jp++);
- oct_it((long) chk, 8, hb.dbuf.chksum);
+ oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
hb.dbuf.chksum[6] = '\0';
(void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
/****************************************************************************
(Un)mangle DOS pathname, make nonabsolute
****************************************************************************/
-static void fixtarname(char *tptr, char *fp, int l)
+static void fixtarname(char *tptr, const char *fp, int l)
{
/* add a '.' to start of file name, convert from ugly dos \'s in path
* to lovely unix /'s :-} */
/****************************************************************************
Convert from decimal to octal string
****************************************************************************/
-static void oct_it (long value, int ndgs, char *p)
+static void oct_it (SMB_BIG_UINT value, int ndgs, char *p)
{
/* Converts long to octal string, pads with leading zeros */
if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
/* check for s1 is an "initial" string of s2 */
- if (*s2 == '/' || *s2 == '\\') return 0;
+ if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0;
return *s1-*s2;
}
static void do_atar(char *rname,char *lname,file_info *finfo1)
{
int fnum;
- uint32 nread=0;
+ SMB_BIG_UINT nread=0;
char ftype;
file_info2 finfo;
BOOL close_done = False;
finfo.mtime = finfo1 -> mtime;
finfo.atime = finfo1 -> atime;
finfo.ctime = finfo1 -> ctime;
+ finfo.name = finfo1 -> name;
}
else {
finfo.size = def_finfo.size;
finfo.mtime = def_finfo.mtime;
finfo.atime = def_finfo.atime;
finfo.ctime = def_finfo.ctime;
+ finfo.name = def_finfo.name;
}
if (dry_run)
{
- DEBUG(3,("skipping file %s of size %d bytes\n",
+ DEBUG(3,("skipping file %s of size %12.0f bytes\n",
finfo.name,
- (int)finfo.size));
+ (double)finfo.size));
shallitime=0;
ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
ntarf++;
}
else
{
- DEBUG(3,("getting file %s of size %d bytes as a tar file %s",
+ DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
finfo.name,
- (int)finfo.size,
+ (double)finfo.size,
lname));
/* write a tar header, don't bother with mode - just set to 100644 */
while (nread < finfo.size && !close_done) {
- DEBUG(3,("nread=%d\n",nread));
+ DEBUG(3,("nread=%.0f\n",(double)nread));
datalen = cli_read(cli, fnum, data, nread, read_size);
if (nread > finfo.size) {
datalen -= nread - finfo.size;
- DEBUG(0,("File size change - truncating %s to %d bytes\n", finfo.name, (int)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
/* 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=%d, nread=%d\n", (int)finfo.size, (int)nread));
+ 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)));
}
if (tar_noisy)
{
- DEBUG(0, ("%10d (%7.1f kb/s) %s\n",
- (int)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
+ DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
+ (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
finfo.name));
}
DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
- safe_strcpy(exclaim, cur_dir, sizeof(pstring));
+ pstrcpy(exclaim, cur_dir);
*(exclaim+strlen(exclaim)-1)='\0';
- safe_strcat(exclaim, "\\", sizeof(pstring));
- safe_strcat(exclaim, finfo->name, sizeof(exclaim));
+ pstrcat(exclaim, "\\");
+ pstrcat(exclaim, finfo->name);
DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
pstring saved_curdir;
pstring mtar_mask;
- safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir));
+ pstrcpy(saved_curdir, cur_dir);
DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir));
- safe_strcat(cur_dir,finfo->name, sizeof(cur_dir));
- safe_strcat(cur_dir,"\\", sizeof(cur_dir));
+ pstrcat(cur_dir,finfo->name);
+ pstrcat(cur_dir,"\\");
DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
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));
+ pstrcpy(mtar_mask,cur_dir);
+ pstrcat(mtar_mask,"*");
DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
do_list(mtar_mask, attribute, do_tar, False, True);
- safe_strcpy(cur_dir,saved_curdir, sizeof(pstring));
+ pstrcpy(cur_dir,saved_curdir);
}
else
{
- safe_strcpy(rname,cur_dir, sizeof(pstring));
- safe_strcat(rname,finfo->name, sizeof(pstring));
+ pstrcpy(rname,cur_dir);
+ pstrcat(rname,finfo->name);
do_atar(rname,finfo->name,finfo);
}
}
static int get_file(file_info2 finfo)
{
- int fnum = -1, pos = 0, dsize = 0, rsize = 0, bpos = 0;
+ int fnum = -1, pos = 0, dsize = 0, bpos = 0;
+ SMB_BIG_UINT rsize = 0;
- DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, (int)finfo.size));
+ DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
if (ensurepath(finfo.name) &&
(fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
ntarf++;
- DEBUG(0, ("restore tar file %s of size %d bytes\n", finfo.name, (int)finfo.size));
+ DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size));
return(True);
}
*/
static char * get_longfilename(file_info2 finfo)
{
- int namesize = finfo.size + strlen(cur_dir) + 2;
+ int namesize = strlen(finfo.name) + 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));
+ DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
if (longname == NULL) {
DEBUG(0, ("could not allocate buffer of size %d for longname\n",
- (int)(finfo.size + strlen(cur_dir) + 2)));
+ namesize));
return(NULL);
}
/****************************************************************************
Blocksize command
***************************************************************************/
-void cmd_block(void)
+int cmd_block(void)
{
fstring buf;
int block;
if (!next_token_nr(NULL,buf,NULL,sizeof(buf)))
{
DEBUG(0, ("blocksize <n>\n"));
- return;
+ return 1;
}
block=atoi(buf);
if (block < 0 || block > 65535)
{
DEBUG(0, ("blocksize out of range"));
- return;
+ return 1;
}
blocksize=block;
DEBUG(2,("blocksize is now %d\n", blocksize));
+
+ return 0;
}
/****************************************************************************
command to set incremental / reset mode
***************************************************************************/
-void cmd_tarmode(void)
+int cmd_tarmode(void)
{
fstring buf;
tar_reset ? "reset" : "noreset",
tar_noisy ? "verbose" : "quiet"));
+ return 0;
}
/****************************************************************************
Feeble attrib command
***************************************************************************/
-void cmd_setmode(void)
+int cmd_setmode(void)
{
char *q;
fstring buf;
if (!next_token_nr(NULL,buf,NULL,sizeof(buf)))
{
DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
- return;
+ return 1;
}
- safe_strcpy(fname, cur_dir, sizeof(pstring));
- safe_strcat(fname, buf, sizeof(pstring));
+ pstrcpy(fname, cur_dir);
+ pstrcat(fname, buf);
while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
q=buf;
case 'a': attra[direct]|=aARCH;
break;
default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
- return;
+ return 1;
}
}
if (attra[ATTRSET]==0 && attra[ATTRRESET]==0)
{
DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
- return;
+ 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
***************************************************************************/
-void cmd_tar(void)
+int cmd_tar(void)
{
fstring buf;
char **argl;
if (!next_token_nr(NULL,buf,NULL,sizeof(buf)))
{
DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
- return;
+ return 1;
}
argl=toktocliplist(&argcl, NULL);
if (!tar_parseargs(argcl, argl, buf, 0))
- return;
+ return 1;
process_tar();
SAFE_FREE(argl);
+
+ return 0;
}
/****************************************************************************
if (strrchr_m(cliplist[i], '\\')) {
pstring saved_dir;
- safe_strcpy(saved_dir, cur_dir, sizeof(pstring));
+ pstrcpy(saved_dir, cur_dir);
if (*cliplist[i]=='\\') {
- safe_strcpy(tarmac, cliplist[i], sizeof(pstring));
+ pstrcpy(tarmac, cliplist[i]);
} else {
- safe_strcpy(tarmac, cur_dir, sizeof(pstring));
- safe_strcat(tarmac, cliplist[i], sizeof(pstring));
+ pstrcpy(tarmac, cur_dir);
+ pstrcat(tarmac, cliplist[i]);
}
- safe_strcpy(cur_dir, tarmac, sizeof(pstring));
+ pstrcpy(cur_dir, tarmac);
*(strrchr_m(cur_dir, '\\')+1)='\0';
DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
do_list(tarmac,attribute,do_tar, False, True);
- safe_strcpy(cur_dir,saved_dir, sizeof(pstring));
+ pstrcpy(cur_dir,saved_dir);
} else {
- safe_strcpy(tarmac, cur_dir, sizeof(pstring));
- safe_strcat(tarmac, cliplist[i], sizeof(pstring));
+ pstrcpy(tarmac, cur_dir);
+ pstrcat(tarmac, cliplist[i]);
DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
do_list(tarmac,attribute,do_tar, False, True);
}
}
} else {
pstring mask;
- safe_strcpy(mask,cur_dir, sizeof(pstring));
+ pstrcpy(mask,cur_dir);
DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
- safe_strcat(mask,"\\*", sizeof(pstring));
+ pstrcat(mask,"\\*");
do_list(mask,attribute,do_tar,False, True);
}
if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0))
{
if (!dry_run) {
- DEBUG(0,("Output is /dev/null, assuming dry_run"));
+ DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
dry_run = True;
}
tarhandle=-1;