#include "includes.h"
+#include "system/filesys.h"
#include "clitar.h"
#include "client/client_proto.h"
#define ATTRSET 1
#define ATTRRESET 0
-static uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
+static uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
#ifndef CLIENT_TIMEOUT
#define CLIENT_TIMEOUT (30*1000)
static int blocksize=20;
static int tarhandle;
-static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
+static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime,
const char *amode, unsigned char ftype);
-static void do_atar(const char *rname_in,char *lname,file_info *finfo1);
-static void do_tar(file_info *finfo, const char *dir);
-static void oct_it(SMB_BIG_UINT value, int ndgs, char *p);
+static NTSTATUS do_atar(const char *rname_in, char *lname,
+ struct file_info *finfo1);
+static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
+ const char *dir);
+static void oct_it(uint64_t value, int ndgs, char *p);
static void fixtarname(char *tptr, const char *fp, size_t l);
static int dotarbuf(int f, char *b, int n);
static void dozerobuf(int f, int n);
* tar specific utitlities
*/
-/*******************************************************************
-Create a string of size size+1 (for the null)
-*******************************************************************/
-
-static char *string_create_s(int size)
-{
- char *tmp;
-
- tmp = (char *)SMB_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, SMB_BIG_UINT size, time_t mtime,
+static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime,
const char *amode, unsigned char ftype)
{
union hblock hb;
/* write out a "standard" tar format header */
hb.dbuf.name[NAMSIZ-1]='\0';
- safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
- oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
- oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
- oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
- if (size > (SMB_BIG_UINT)077777777777LL) {
+ strlcpy(hb.dbuf.mode, amode ? amode : "", sizeof(hb.dbuf.mode));
+ 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);
+ if (size > (uint64_t)077777777777LL) {
/* This is a non-POSIX compatible extention to store files
greater than 8GB. */
for (i = 8, jp=(char*)&size; i; i--)
hb.dbuf.size[i+3] = *(jp++);
}
- oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
+ 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((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
+ oct_it((uint64_t) chk, 8, hb.dbuf.chksum);
hb.dbuf.chksum[6] = '\0';
(void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
return -1;
}
- if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) {
+ if ((finfo->name = SMB_MALLOC(strlen(prefix) + strlen(hb -> dbuf.name) + 4)) == 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);
+ strlcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 4);
/* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) ||
(*(finfo->name+strlen(finfo->name)-1) == '\\')) {
- finfo->mode=aDIR;
+ 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 */
diff=tbufsiz-tp;
memcpy(tarbuf + tp, b, diff);
- fail=fail && (1+write(f, tarbuf, tbufsiz));
+ fail=fail && (1+sys_write(f, tarbuf, tbufsiz));
n-=diff;
b+=diff;
tp=0;
while (n >= tbufsiz) {
- fail=fail && (1 + write(f, b, tbufsiz));
+ fail=fail && (1 + sys_write(f, b, tbufsiz));
n-=tbufsiz;
b+=tbufsiz;
}
if (n+tp >= tbufsiz) {
memset(tarbuf+tp, 0, tbufsiz-tp);
- write(f, tarbuf, tbufsiz);
+ if (sys_write(f, tarbuf, tbufsiz) != tbufsiz) {
+ DEBUG(0, ("dozerobuf: sys_write fail\n"));
+ return;
+ }
memset(tarbuf, 0, (tp+=n-tbufsiz));
} else {
memset(tarbuf+tp, 0, n);
(void) dozerobuf(f, TBLOCK);
(void) dozerobuf(f, TBLOCK);
- if (sys_fstat(f, &stbuf) == -1) {
+ if (sys_fstat(f, &stbuf, false) == -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);
+ if (tp > 0) {
+ size_t towrite = S_ISREG(stbuf.st_ex_mode) ? tp : tbufsiz;
+ if (sys_write(f, tarbuf, towrite) != towrite) {
+ DEBUG(0,("dotareof: sys_write fail\n"));
+ }
+ }
}
/****************************************************************************
Convert from decimal to octal string
****************************************************************************/
-static void oct_it (SMB_BIG_UINT value, int ndgs, char *p)
+static void oct_it (uint64_t value, int ndgs, char *p)
{
/* Converts long to octal string, pads with leading zeros */
/* ensures path exists */
char *partpath, *ffname;
+ size_t fnamelen = strlen(fname)+1;
const char *p=fname;
char *basehack;
char *saveptr;
DEBUG(5, ( "Ensurepath called with: %s\n", fname));
- partpath = string_create_s(strlen(fname));
- ffname = string_create_s(strlen(fname));
+ partpath = SMB_MALLOC(fnamelen);
+ ffname = SMB_MALLOC(fnamelen);
if ((partpath == NULL) || (ffname == NULL)){
DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
/* fname copied to ffname so can strtok_r */
- safe_strcpy(ffname, fname, strlen(fname));
+ strlcpy(ffname, fname, fnamelen);
/* do a `basename' on ffname, so don't try and make file name directory */
if ((basehack=strrchr_m(ffname, '\\')) == NULL) {
p=strtok_r(ffname, "\\", &saveptr);
while (p) {
- safe_strcat(partpath, p, strlen(fname) + 1);
+ strlcat(partpath, p, fnamelen);
- if (!cli_chkpath(cli, partpath)) {
- if (!cli_mkdir(cli, partpath)) {
+ if (!NT_STATUS_IS_OK(cli_chkpath(cli, partpath))) {
+ if (!NT_STATUS_IS_OK(cli_mkdir(cli, partpath))) {
SAFE_FREE(partpath);
SAFE_FREE(ffname);
DEBUG(0, ("Error mkdir %s\n", cli_errstr(cli)));
}
}
- safe_strcat(partpath, "\\", strlen(fname) + 1);
+ strlcat(partpath, "\\", fnamelen);
p = strtok_r(NULL, "/\\", &saveptr);
}
return True;
}
-static int padit(char *buf, SMB_BIG_UINT bufsize, SMB_BIG_UINT padsize)
+static int padit(char *buf, uint64_t bufsize, uint64_t padsize)
{
int berr= 0;
int bytestowrite;
{
uint16 oldattr;
- if (!cli_getatr(cli, name, &oldattr, NULL, NULL)) return;
+ if (!NT_STATUS_IS_OK(cli_getatr(cli, name, &oldattr, NULL, NULL))) {
+ return;
+ }
if (set == ATTRSET) {
attr |= oldattr;
attr = oldattr & ~attr;
}
- if (!cli_setatr(cli, name, attr, 0)) {
+ if (!NT_STATUS_IS_OK(cli_setatr(cli, name, attr, 0))) {
DEBUG(1,("setatr failed: %s\n", cli_errstr(cli)));
}
}
append one remote file to the tar file
***************************************************************************/
-static void do_atar(const char *rname_in,char *lname,file_info *finfo1)
+static NTSTATUS do_atar(const char *rname_in, char *lname,
+ struct file_info *finfo1)
{
- int fnum = -1;
- SMB_BIG_UINT nread=0;
+ uint16_t fnum = (uint16_t)-1;
+ uint64_t nread=0;
char ftype;
file_info2 finfo;
bool shallitime=True;
int datalen=0;
char *rname = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
+ NTSTATUS status = NT_STATUS_OK;
+ struct timespec tp_start;
- struct timeval tp_start;
-
- GetTimeOfDay(&tp_start);
+ clock_gettime_mono(&tp_start);
data = SMB_MALLOC_ARRAY(char, read_size);
if (!data) {
DEBUG(0,("do_atar: out of memory.\n"));
+ status = NT_STATUS_NO_MEMORY;
goto cleanup;
}
rname = clean_name(ctx, rname_in);
if (!rname) {
+ status = NT_STATUS_NO_MEMORY;
goto cleanup;
}
- fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
-
- if (fnum == -1) {
+ status = cli_open(cli, rname, O_RDONLY, DENY_NONE, &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("%s opening remote file %s (%s)\n",
cli_errstr(cli),rname, client_get_cur_dir()));
goto cleanup;
}
- finfo.name = string_create_s(strlen(rname));
+ finfo.name = smb_xstrdup(rname);
if (finfo.name == NULL) {
DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
+ status = NT_STATUS_NO_MEMORY;
goto cleanup;
}
- safe_strcpy(finfo.name,rname, strlen(rname));
-
DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
- if (tar_inc && !(finfo.mode & aARCH)) {
+ 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 & aSYSTEM)) {
+ } 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 & aHIDDEN)) {
+ } else if (!tar_hidden && (finfo.mode & FILE_ATTRIBUTE_HIDDEN)) {
DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
shallitime=0;
} else {
if (datalen == -1) {
DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
+ status = cli_nt_error(cli);
break;
}
if (dotarbuf(tarhandle,data,datalen) != datalen) {
DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
+ status = map_nt_error_from_unix(errno);
break;
}
if ( (datalen == 0) && (finfo.size != 0) ) {
+ status = NT_STATUS_UNSUCCESSFUL;
DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
break;
}
if (nread < finfo.size) {
DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
(double)finfo.size, (int)nread));
- if (padit(data, (SMB_BIG_UINT)sizeof(data), finfo.size - nread))
+ if (padit(data, (uint64_t)sizeof(data), finfo.size - nread)) {
+ status = map_nt_error_from_unix(errno);
DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
+ }
}
/* round tar file to nearest block */
} else {
DEBUG(4, ("skipping %s - initial read failed (file was locked ?)\n", finfo.name));
shallitime=0;
+ status = NT_STATUS_UNSUCCESSFUL;
}
}
fnum = -1;
if (shallitime) {
- struct timeval tp_end;
+ struct timespec tp_end;
int this_time;
/* if shallitime is true then we didn't skip */
if (tar_reset && !dry_run)
- (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
+ (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;
+ clock_gettime_mono(&tp_end);
+ this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_nsec - tp_start.tv_nsec)/1000000;
get_total_time_ms += this_time;
get_total_size += finfo.size;
cleanup:
- if (fnum != -1) {
+ if (fnum != (uint16_t)-1) {
cli_close(cli, fnum);
fnum = -1;
}
TALLOC_FREE(ctx);
SAFE_FREE(data);
+ return status;
}
/****************************************************************************
Append single file to tar file (or not)
***************************************************************************/
-static void do_tar(file_info *finfo, const char *dir)
+static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo,
+ const char *dir)
{
TALLOC_CTX *ctx = talloc_stackframe();
+ NTSTATUS status = NT_STATUS_OK;
if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
- return;
+ return NT_STATUS_OK;
/* Is it on the exclude list ? */
if (!tar_excl && clipn) {
client_get_cur_dir(),
finfo->name);
if (!exclaim) {
- return;
+ return NT_STATUS_NO_MEMORY;
}
DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
(tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) {
DEBUG(3,("Skipping file %s\n", exclaim));
TALLOC_FREE(exclaim);
- return;
+ return NT_STATUS_OK;
}
TALLOC_FREE(exclaim);
}
- if (finfo->mode & aDIR) {
+ if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
char *saved_curdir = NULL;
char *new_cd = NULL;
char *mtar_mask = NULL;
saved_curdir = talloc_strdup(ctx, client_get_cur_dir());
if (!saved_curdir) {
- return;
+ return NT_STATUS_NO_MEMORY;
}
DEBUG(5, ("strlen(cur_dir)=%d, \
client_get_cur_dir(),
finfo->name);
if (!new_cd) {
- return;
+ return NT_STATUS_NO_MEMORY;
}
client_set_cur_dir(new_cd);
"%s*",
client_get_cur_dir());
if (!mtar_mask) {
- return;
+ return NT_STATUS_NO_MEMORY;
}
DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
- do_list(mtar_mask, attribute, do_tar, False, True);
+ status = do_list(mtar_mask, attribute, do_tar, False, True);
client_set_cur_dir(saved_curdir);
TALLOC_FREE(saved_curdir);
TALLOC_FREE(new_cd);
client_get_cur_dir(),
finfo->name);
if (!rname) {
- return;
+ return NT_STATUS_NO_MEMORY;
}
- do_atar(rname,finfo->name,finfo);
+ status = do_atar(rname,finfo->name,finfo);
TALLOC_FREE(rname);
}
+ return status;
}
/****************************************************************************
fp++;
l--;
}
+ if (l <= 0) {
+ return;
+ }
}
- safe_strcpy(tptr, fp, l);
+ strlcpy(tptr, fp, l);
string_replace(tptr, '/', '\\');
}
static int get_file(file_info2 finfo)
{
- int fnum = -1, pos = 0, dsize = 0, bpos = 0;
- SMB_BIG_UINT rsize = 0;
+ uint16_t fnum = (uint16_t) -1;
+ int pos = 0, dsize = 0, bpos = 0;
+ uint64_t rsize = 0;
+ NTSTATUS status;
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) {
+ if (!ensurepath(finfo.name)) {
DEBUG(0, ("abandoning restore\n"));
- return(False);
+ return False;
+ }
+
+ status = cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("abandoning restore\n"));
+ return False;
}
/* read the blocks from the tar file and write to the remote file */
dsize = MIN(dsize, rsize); /* Should be only what is left */
DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
- if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
- DEBUG(0, ("Error writing remote file\n"));
+ status = cli_writeall(cli, fnum, 0,
+ (uint8_t *)(buffer_p + bpos), pos,
+ dsize, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Error writing remote file: %s\n",
+ nt_errstr(status)));
return 0;
}
/* Now close the file ... */
- if (!cli_close(cli, fnum)) {
- DEBUG(0, ("Error closing remote file\n"));
+ if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
+ DEBUG(0, ("Error %s closing remote file\n",
+ cli_errstr(cli)));
return(False);
}
/* Now we update the creation date ... */
DEBUG(5, ("Updating creation date on %s\n", finfo.name));
- if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime_ts.tv_sec)) {
+ if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime_ts.tv_sec))) {
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 */
return(NULL);
}
- unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--);
+ unfixtarname(longname + offset, buffer_p,
+ namesize - offset, first--);
DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p));
offset += TBLOCK;
static void do_tarput(void)
{
file_info2 finfo;
- struct timeval tp_start;
+ struct timespec tp_start;
char *longfilename = NULL, linkflag;
int skip = False;
ZERO_STRUCT(finfo);
- GetTimeOfDay(&tp_start);
+ clock_gettime_mono(&tp_start);
DEBUG(5, ("RJS do_tarput called ...\n"));
buffer_p = tarbuf + tbufsiz; /* init this to force first read */
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"));
+ SAFE_FREE(longfilename);
return;
}
break;
case -1:
DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
+ SAFE_FREE(longfilename);
return;
case 0: /* chksum is zero - looks like an EOF */
DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
+ SAFE_FREE(longfilename);
return; /* Hmmm, bad here ... */
default:
direct=0;
break;
case 'r':
- attra[direct]|=aRONLY;
+ attra[direct]|=FILE_ATTRIBUTE_READONLY;
break;
case 'h':
- attra[direct]|=aHIDDEN;
+ attra[direct]|=FILE_ATTRIBUTE_HIDDEN;
break;
case 's':
- attra[direct]|=aSYSTEM;
+ attra[direct]|=FILE_ATTRIBUTE_SYSTEM;
break;
case 'a':
- attra[direct]|=aARCH;
+ attra[direct]|=FILE_ATTRIBUTE_ARCHIVE;
break;
default:
DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
if (strrchr_m(cliplist[i], '\\')) {
char *p;
+ char saved_char;
char *saved_dir = talloc_strdup(ctx,
client_get_cur_dir());
if (!saved_dir) {
if (!tarmac) {
return 1;
}
+ /*
+ * Strip off the last \\xxx
+ * xxx element of tarmac to set
+ * it as current directory.
+ */
p = strrchr_m(tarmac, '\\');
if (!p) {
return 1;
}
+ saved_char = p[1];
p[1] = '\0';
+
client_set_cur_dir(tarmac);
+ /*
+ * Restore the character we
+ * just replaced to
+ * put the pathname
+ * back as it was.
+ */
+ p[1] = saved_char;
+
DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
do_list(tarmac,attribute,do_tar, False, True);
}
}
- safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
+ strlcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
inclusion_buffer_sofar += strlen(buf) + 1;
clipn++;
}
} else {
SMB_STRUCT_STAT stbuf;
- if (sys_stat(argv[Optind], &stbuf) == 0) {
- newer_than = stbuf.st_mtime;
+ if (sys_stat(argv[Optind], &stbuf,
+ false) == 0) {
+ newer_than = convert_timespec_to_time_t(
+ stbuf.st_ex_mtime);
DEBUG(1,("Getting files newer than %s",
time_to_asc(newer_than)));
newOptind++;
* tar output
*/
if (tarhandle == 1) {
- dbf = x_stderr;
+ setup_logging("smbclient", DEBUG_STDERR);
}
if (!argv[Optind]) {
DEBUG(0,("Must specify tar filename\n"));