📄 clitar.c
字号:
while (total < bufsiz) { if (bufread < 0) { /* An error, return false */ return (total > 0 ? -2 : bufread); } if (bufread == 0) { if (total <= 0) { return -2; } break; } bufread = read(tarhandle, <arbuf[total], bufsiz - total); total += bufread; } DEBUG(5, ("Total bytes read ... %i\n", total)); *bufferp = ltarbuf; } return(total);}/* Skip a file, even if it includes a long file name? */static int skip_file(int skipsize){ int dsize = skipsize; DEBUG(5, ("Skiping file. Size = %i\n", skipsize)); /* FIXME, we should skip more than one block at a time */ while (dsize > 0) { if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); return(False); } dsize -= TBLOCK; } return(True);}/************************************************************* Get a file from the tar file and store it. When this is called, tarbuf already contains the first file block. This is a bit broken & needs fixing.**************************************************************/static int get_file(file_info2 finfo){ int fnum = -1, pos = 0, dsize = 0, bpos = 0; SMB_BIG_UINT rsize = 0; 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) { DEBUG(0, ("abandoning restore\n")); return(False); } /* read the blocks from the tar file and write to the remote file */ rsize = finfo.size; /* This is how much to write */ while (rsize > 0) { /* We can only write up to the end of the buffer */ dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */ 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")); return 0; } rsize -= dsize; pos += dsize; /* Now figure out how much to move in the buffer */ /* FIXME, we should skip more than one block at a time */ /* First, skip any initial part of the part written that is left over */ /* from the end of the first TBLOCK */ if ((bpos) && ((bpos + dsize) >= TBLOCK)) { dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */ bpos = 0; if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); return False; } } /* * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>. * If the file being extracted is an exact multiple of * TBLOCK bytes then we don't want to extract the next * block from the tarfile here, as it will be done in * the caller of get_file(). */ while (((rsize != 0) && (dsize >= TBLOCK)) || ((rsize == 0) && (dsize > TBLOCK))) { if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); return False; } dsize -= TBLOCK; } bpos = dsize; } /* Now close the file ... */ if (!cli_close(cli, fnum)) { DEBUG(0, ("Error closing remote file\n")); 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)) { 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 */ } } ntarf++; DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size)); return(True);}/* Create a directory. We just ensure that the path exists and return as there is no file associated with a directory */static int get_dir(file_info2 finfo){ DEBUG(0, ("restore directory %s\n", finfo.name)); if (!ensurepath(finfo.name)) { DEBUG(0, ("Problems creating directory\n")); return(False); } ntarf++; return(True);}/* Get a file with a long file name ... first file has file name, next file has the data. We only want the long file name, as the loop in do_tarput will deal with the rest.*/static char *get_longfilename(file_info2 finfo){ /* finfo.size here is the length of the filename as written by the "/./@LongLink" name * header call. */ int namesize = finfo.size + strlen(cur_dir) + 2; char *longname = SMB_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 = %.0f\n", (double)finfo.size)); if (longname == NULL) { DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize)); return(NULL); } /* First, add cur_dir to the long file name */ if (strlen(cur_dir) > 0) { strncpy(longname, cur_dir, namesize); offset = strlen(cur_dir); } /* Loop through the blocks picking up the name */ while (left > 0) { if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); return(NULL); } unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--); DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p)); offset += TBLOCK; left -= TBLOCK; } return(longname);}static void do_tarput(void){ file_info2 finfo; struct timeval tp_start; char *longfilename = NULL, linkflag; int skip = False; ZERO_STRUCT(finfo); GetTimeOfDay(&tp_start); DEBUG(5, ("RJS do_tarput called ...\n")); buffer_p = tarbuf + tbufsiz; /* init this to force first read */ /* Now read through those files ... */ while (True) { /* Get us to the next block, or the first block first time around */ if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) { DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno))); return; } DEBUG(5, ("Reading the next header ...\n")); switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) { case -2: /* Hmm, not good, but not fatal */ 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")); return; } break; case -1: DEBUG(0, ("abandoning restore, -1 from read tar header\n")); return; case 0: /* chksum is zero - looks like an EOF */ DEBUG(0, ("tar: restored %d files and directories\n", ntarf)); return; /* Hmmm, bad here ... */ default: /* No action */ break; } /* Now, do we have a long file name? */ if (longfilename != NULL) { SAFE_FREE(finfo.name); /* Free the space already allocated */ finfo.name = longfilename; longfilename = NULL; } /* Well, now we have a header, process the file ... */ /* Should we skip the file? We have the long name as well here */ skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) || (tar_re_search && mask_match_list(finfo.name, cliplist, clipn, True))); DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name)); if (skip) { skip_file(finfo.size); continue; } /* We only get this far if we should process the file */ linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag; switch (linkflag) { case '0': /* Should use symbolic names--FIXME */ /* * Skip to the next block first, so we can get the file, FIXME, should * be in get_file ... * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net> * Fixes bug where file size in tarfile is zero. */ if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) { DEBUG(0, ("Short file, bailing out...\n")); return; } if (!get_file(finfo)) { DEBUG(0, ("Abandoning restore\n")); return; } break; case '5': if (!get_dir(finfo)) { DEBUG(0, ("Abandoning restore \n")); return; } break; case 'L': longfilename = get_longfilename(finfo); if (!longfilename) { DEBUG(0, ("abandoning restore\n")); return; } DEBUG(5, ("Long file name: %s\n", longfilename)); break; default: skip_file(finfo.size); /* Don't handle these yet */ break; } }}/* * samba interactive commands *//****************************************************************************Blocksize command***************************************************************************/int cmd_block(void){ fstring buf; int block; if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { DEBUG(0, ("blocksize <n>\n")); return 1; } block=atoi(buf); if (block < 0 || block > 65535) { DEBUG(0, ("blocksize out of range")); return 1; } blocksize=block; DEBUG(2,("blocksize is now %d\n", blocksize)); return 0;}/****************************************************************************command to set incremental / reset mode***************************************************************************/int cmd_tarmode(void){ fstring buf; while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { if (strequal(buf, "full")) tar_inc=False; else if (strequal(buf, "inc")) tar_inc=True; else if (strequal(buf, "reset")) 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, %s, %s, %s\n", tar_inc ? "incremental" : "full", tar_system ? "system" : "nosystem", tar_hidden ? "hidden" : "nohidden", tar_reset ? "reset" : "noreset", tar_noisy ? "verbose" : "quiet")); return 0;}/****************************************************************************Feeble attrib command***************************************************************************/int cmd_setmode(void){ char *q; fstring buf; pstring fname; uint16 attra[2]; int direct=1; attra[0] = attra[1] = 0; if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) { DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); return 1; } pstrcpy(fname, cur_dir); pstrcat(fname, buf); while (next_token_nr(NULL,buf,NULL,sizeof(buf))) { q=buf; while(*q) { switch (*q++) { case '+': direct=1; break; case '-': direct=0; break; case 'r': attra[direct]|=aRONLY; break; case 'h': attra[direct]|=aHIDDEN; break; case 's': attra[direct]|=aSYSTEM; break; case 'a': attra[direct]|=aARCH; break; default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n")); return 1; } } } if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) { DEBUG(0, ("setmode <filename> <[+|-]rsha>\n")); 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***************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -