📄 clitar.c
字号:
do { p[--ndgs] = '0' + (char) (value & 7); value >>= 3; } while (ndgs > 0 && value != 0); /* Do leading zeros */ while (ndgs > 0) p[--ndgs] = '0';}/****************************************************************************Convert from octal string to long***************************************************************************/static long unoct(char *p, int ndgs){ long value=0; /* Converts octal string to long, ignoring any non-digit */ while (--ndgs) { if (isdigit((int)*p)) value = (value << 3) | (long) (*p - '0'); p++; } return value;}/****************************************************************************Compare two strings in a slash insensitive way, allowing s1 to match s2 if s1 is an "initial" string (up to directory marker). Thus, if s2 is a file in any subdirectory of s1, declare a match.***************************************************************************/static int strslashcmp(char *s1, char *s2){ char *s1_0=s1; while(*s1 && *s2 && (*s1 == *s2 || tolower_ascii(*s1) == tolower_ascii(*s2) || (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) { s1++; s2++; } /* if s1 has a trailing slash, it compared equal, so s1 is an "initial" string of s2. */ if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) return 0; /* ignore trailing slash on s1 */ if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0; /* check for s1 is an "initial" string of s2 */ if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0; return *s1-*s2;}/****************************************************************************Ensure a remote path exists (make if necessary)***************************************************************************/static BOOL ensurepath(char *fname){ /* *must* be called with buffer ready malloc'ed */ /* ensures path exists */ char *partpath, *ffname; char *p=fname, *basehack; DEBUG(5, ( "Ensurepath called with: %s\n", fname)); partpath = string_create_s(strlen(fname)); ffname = string_create_s(strlen(fname)); if ((partpath == NULL) || (ffname == NULL)){ DEBUG(0, ("Out of memory in ensurepath: %s\n", fname)); return(False); } *partpath = 0; /* fname copied to ffname so can strtok */ safe_strcpy(ffname, fname, strlen(fname)); /* do a `basename' on ffname, so don't try and make file name directory */ if ((basehack=strrchr_m(ffname, '\\')) == NULL) return True; else *basehack='\0'; p=strtok(ffname, "\\"); while (p) { safe_strcat(partpath, p, strlen(fname) + 1); if (!cli_chkpath(cli, partpath)) { if (!cli_mkdir(cli, partpath)) { DEBUG(0, ("Error mkdirhiering\n")); return False; } else { DEBUG(3, ("mkdirhiering %s\n", partpath)); } } safe_strcat(partpath, "\\", strlen(fname) + 1); p = strtok(NULL,"/\\"); } return True;}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;}static void do_setrattr(char *name, uint16 attr, int set){ uint16 oldattr; if (!cli_getatr(cli, name, &oldattr, NULL, NULL)) return; if (set == ATTRSET) { attr |= oldattr; } else { attr = oldattr & ~attr; } if (!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(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 (ease@mail.wirehub.nl) 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)))); }}/****************************************************************************Append single file to tar file (or not)***************************************************************************/static void do_tar(file_info *finfo){ pstring rname; if (strequal(finfo->name,"..") || strequal(finfo->name,".")) return; /* Is it on the exclude list ? */ if (!tar_excl && clipn) { pstring exclaim; DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir))); pstrcpy(exclaim, cur_dir); *(exclaim+strlen(exclaim)-1)='\0'; pstrcat(exclaim, "\\"); pstrcat(exclaim, finfo->name); DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) || (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) { DEBUG(3,("Skipping file %s\n", exclaim)); return; } } if (finfo->mode & aDIR) { pstring saved_curdir; pstring mtar_mask; 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)); pstrcat(cur_dir,finfo->name); pstrcat(cur_dir,"\\"); DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir)); /* write a tar directory, don't bother with mode - just set it to * 40755 */ writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5'); if (tar_noisy) { DEBUG(0,(" directory %s\n", cur_dir)); } ntarf++; /* Make sure we have a file on there */ 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); pstrcpy(cur_dir,saved_curdir); } else { pstrcpy(rname,cur_dir); pstrcat(rname,finfo->name); do_atar(rname,finfo->name,finfo); }}/****************************************************************************Convert from UNIX to DOS file names***************************************************************************/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--; } } safe_strcpy(tptr, fp, l); string_replace(tptr, '/', '\\');}/****************************************************************************Move to the next block in the buffer, which may mean read in another set ofblocks. FIXME, we should allow more than one block to be skipped.****************************************************************************/static int next_block(char *ltarbuf, char **bufferp, int bufsiz){ int bufread, total = 0; DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp)); *bufferp += TBLOCK; total = TBLOCK; if (*bufferp >= (ltarbuf + bufsiz)) { DEBUG(5, ("Reading more data into ltarbuf ...\n")); /* * Bugfix from Bob Boehmer <boehmer@worldnet.att.net> * Fixes bug where read can return short if coming from * a pipe. */ bufread = read(tarhandle, ltarbuf, bufsiz); total = bufread;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -