示例#1
0
/****************************************************************************
Write a tar header to buffer
****************************************************************************/
static void writetarheader(int f,  char *aname, SMB_BIG_UINT size, time_t mtime,
			   char *amode, unsigned char 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) {
	  /* 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);
	  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);
  }

  /* 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((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);
  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((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
  hb.dbuf.chksum[6] = '\0';

  (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
}
示例#2
0
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;
}
示例#3
0
static void do_atar(char *rname,char *lname,file_info *finfo1)
{
	int fnum;
	SMB_BIG_UINT 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  = finfo1 -> name;
	} else {
		finfo.size  = def_finfo.size;
		finfo.mode  = def_finfo.mode;
		finfo.uid   = def_finfo.uid;
		finfo.gid   = def_finfo.gid;
		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 %12.0f bytes\n", finfo.name,
				(double)finfo.size));
		shallitime=0;
		ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
		ntarf++;
		return;
	}

	fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);

	dos_clean_name(rname);

	if (fnum == -1) {
		DEBUG(0,("%s opening remote file %s (%s)\n",
				cli_errstr(cli),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) {
		if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
			DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
			return;
		}
		finfo.ctime = finfo.mtime;
	}

	DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));

	if (tar_inc && !(finfo.mode & aARCH)) {
		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 {
		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 = cli_read(cli, fnum, data, nread, read_size);
	      
			if (datalen == -1) {
				DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
				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++;
	}
  
	cli_close(cli, 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, aARCH, 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 ([email protected]) 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))));
	}
}
示例#4
0
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= %.0f, Name = %s\n", ftype, (double)size, aname));

	memset(hb.dummy, 0, sizeof(hb.dummy));
  
	l=strlen(aname);
	/* We will be prepending a '.' in fixtarheader so use +2 to
	 * take care of the . and terminating zero. JRA.
	 */
	if (l+2 >= 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+2, 0, "     0 \0", 'L');
		memset(b, 0, l+TBLOCK+100);
		fixtarname(b, aname, l+2);
		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);
	}

	fixtarname(hb.dbuf.name, aname, (l+2 >= NAMSIZ) ? NAMSIZ : l + 2);

	if (lowercase)
		strlower_m(hb.dbuf.name);

	/* 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) {    

		/* 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((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
	hb.dbuf.chksum[6] = '\0';

	(void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
}