/*
- 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);
} stack;
-stack dir_stack = {NULL, 0}; /* Want an empty stack */
-
#define SEPARATORS " \t\n\r"
-extern int DEBUGLEVEL;
extern struct cli_state *cli;
-extern FILE *dbf;
/* These defines are for the do_setrattr routine, to indicate
* setting and reseting of file attributes in the function call */
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 pstring cur_dir;
extern int get_total_time_ms;
extern int get_total_size;
-extern int Protocol;
-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);
memset(hb.dummy, 0, sizeof(hb.dummy));
l=strlen(aname);
- if (l >= NAMSIZ) {
+ if (l >= NAMSIZ - 1) {
/* write a GNU tar style long header */
char *b;
b = (char *)malloc(l+TBLOCK+100);
DEBUG(0,("out of memory\n"));
exit(1);
}
- writetarheader(f, "/./@LongLink", l+1, 0, " 0 \0", 'L');
+ 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));
- free(b);
+ SAFE_FREE(b);
}
/* use l + 1 to do the null too */
****************************************************************************/
static void fixtarname(char *tptr, char *fp, int l)
{
- /* add a '.' to start of file name, convert from ugly dos \'s in path
- * to lovely unix /'s :-} */
-
- *tptr++='.';
-
- while (l > 0) {
- int skip = get_character_len(*fp);
- if(skip != 0) {
- if (skip == 2) {
- *tptr++ = *fp++;
- *tptr++ = *fp++;
- l -= 2;
- } else if (skip == 1) {
- *tptr++ = *fp++;
- l--;
- }
- } else if (*fp == '\\') {
- *tptr++ = '/';
- fp++;
- l--;
- } else {
- *tptr++ = *fp++;
- 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, '\\', '/');
}
/****************************************************************************
safe_strcpy(ffname, fname, strlen(fname));
/* do a `basename' on ffname, so don't try and make file name directory */
- if ((basehack=strrchr(ffname, '\\')) == NULL)
+ if ((basehack=strrchr_m(ffname, '\\')) == NULL)
return True;
else
*basehack='\0';
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 %d bytes\n", finfo.name, (int)finfo.size));
+ }
+
/* add received bits of file to buffer - dotarbuf will
* write out in 512 byte intervals */
if (dotarbuf(tarhandle,data,datalen) != datalen) {
break;
}
- nread += datalen;
if (datalen == 0) {
DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
break;
***************************************************************************/
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--;
- }
- }
+ /* 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--;
+ }
+ }
- while (l > 0) {
- int skip = get_character_len(*fp);
- if(skip != 0) {
- if (skip == 2) {
- *tptr++ = *fp++;
- *tptr++ = *fp++;
- l -= 2;
- } else if (skip == 1) {
- *tptr++ = *fp++;
- l--;
- }
- } else if (*fp == '/') {
- *tptr++ = '\\';
- fp++;
- l--;
- } else {
- *tptr++ = *fp++;
- l--;
- }
- }
+ safe_strcpy(tptr, fp, l);
+ string_replace(tptr, '/', '\\');
}
if (longfilename != NULL) {
- free(finfo.name); /* Free the space already allocated */
+ SAFE_FREE(finfo.name); /* Free the space already allocated */
finfo.name = longfilename;
longfilename = NULL;
/****************************************************************************
Blocksize command
***************************************************************************/
-void cmd_block(void)
+int cmd_block(void)
{
fstring buf;
int block;
- if (!next_token(NULL,buf,NULL,sizeof(buf)))
+ 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;
- while (next_token(NULL,buf,NULL,sizeof(buf))) {
+ while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
if (strequal(buf, "full"))
tar_inc=False;
else if (strequal(buf, "inc"))
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;
attra[0] = attra[1] = 0;
- if (!next_token(NULL,buf,NULL,sizeof(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));
- while (next_token(NULL,buf,NULL,sizeof(buf))) {
+ while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
q=buf;
while(*q)
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;
int argcl;
- if (!next_token(NULL,buf,NULL,sizeof(buf)))
+ 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();
- free(argl);
+ SAFE_FREE(argl);
+
+ return 0;
}
/****************************************************************************
#else
do_tarput();
#endif
- free(tarbuf);
+ SAFE_FREE(tarbuf);
close(tarhandle);
break;
case 'r':
*(cliplist[i]+strlen(cliplist[i])-1)='\0';
}
- if (strrchr(cliplist[i], '\\')) {
+ if (strrchr_m(cliplist[i], '\\')) {
pstring saved_dir;
safe_strcpy(saved_dir, cur_dir, sizeof(pstring));
safe_strcat(tarmac, cliplist[i], sizeof(pstring));
}
safe_strcpy(cur_dir, tarmac, sizeof(pstring));
- *(strrchr(cur_dir, '\\')+1)='\0';
+ *(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);
if (ntarf) dotareof(tarhandle);
close(tarhandle);
- free(tarbuf);
+ SAFE_FREE(tarbuf);
DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
if (must_free_cliplist) {
int i;
for (i = 0; i < clipn; ++i) {
- free(cliplist[i]);
+ SAFE_FREE(cliplist[i]);
}
- free(cliplist);
+ SAFE_FREE(cliplist);
cliplist = NULL;
clipn = 0;
must_free_cliplist = False;
if (aret==NULL) return 0;
/* ignore leading slashes or dots in token */
- while(strchr("/\\.", *tok)) tok++;
+ while(strchr_m("/\\.", *tok)) tok++;
while(ret--) {
char *pkey=*aret++;
/* ignore leading slashes or dots in list */
- while(strchr("/\\.", *pkey)) pkey++;
+ while(strchr_m("/\\.", *pkey)) pkey++;
if (!strslashcmp(pkey, tok)) return 1;
}
***************************************************************************/
static int read_inclusion_file(char *filename)
{
- FILE *inclusion = NULL;
+ XFILE *inclusion = NULL;
char buf[MAXPATHLEN + 1];
char *inclusion_buffer = NULL;
int inclusion_buffer_size = 0;
clipn = 0;
buf[MAXPATHLEN] = '\0'; /* guarantee null-termination */
- if ((inclusion = sys_fopen(filename, "r")) == NULL) {
+ if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) {
/* XXX It would be better to include a reason for failure, but without
* autoconf, it's hard to use strerror, sys_errlist, etc.
*/
return 0;
}
- while ((! error) && (fgets(buf, sizeof(buf)-1, inclusion))) {
+ while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {
if (inclusion_buffer == NULL) {
inclusion_buffer_size = 1024;
if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) {
}
if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
+ char *ib;
inclusion_buffer_size *= 2;
- inclusion_buffer = Realloc(inclusion_buffer,inclusion_buffer_size);
- if (! inclusion_buffer) {
+ 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++;
}
- fclose(inclusion);
+ x_fclose(inclusion);
if (! error) {
/* Allocate an array of clipn + 1 char*'s for cliplist */
} else {
unfixtarname(tmpstr, p, strlen(p) + 1, True);
cliplist[i] = tmpstr;
- if ((p = strchr(p, '\000')) == NULL) {
+ if ((p = strchr_m(p, '\000')) == NULL) {
DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
abort();
}
}
}
- if (inclusion_buffer) {
- free(inclusion_buffer);
- }
+ SAFE_FREE(inclusion_buffer);
if (error) {
if (cliplist) {
char **pp;
/* We know cliplist is always null-terminated */
for (pp = cliplist; *pp; ++pp) {
- free(*pp);
+ SAFE_FREE(*pp);
}
- free(cliplist);
+ SAFE_FREE(cliplist);
cliplist = NULL;
must_free_cliplist = False;
}
SMB_STRUCT_STAT stbuf;
extern time_t newer_than;
- if (dos_stat(argv[Optind], &stbuf) == 0) {
+ if (sys_stat(argv[Optind], &stbuf) == 0) {
newer_than = stbuf.st_mtime;
DEBUG(1,("Getting files newer than %s",
asctime(LocalTime(&newer_than))));
* tar output
*/
if (tarhandle == 1)
- dbf = stderr;
+ dbf = x_stderr;
} else {
if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0))
{