static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) { struct client_connection *p; int i; for ( p=connections,i=0; p; p=p->next,i++ ) { if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) ) break; } if ( p ) { pstrcpy( p->mount, mnt ); dos_clean_name( p->mount ); } }
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)))); } }
BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, pstring targetpath ) { CLIENT_DFS_REFERRAL *refs = NULL; size_t num_refs; uint16 consumed; struct cli_state *cli_ipc; pstring fullpath, cleanpath; int pathlen; fstring server, share; struct cli_state *newcli; pstring newpath; pstring newmount; char *ppath; SMB_STRUCT_STAT sbuf; uint32 attributes; *targetcli = NULL; if ( !rootcli || !path || !targetcli ) return False; /* send a trans2_query_path_info to check for a referral */ clean_path( cleanpath, path ); make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath ); /* don't bother continuing if this is not a dfs root */ if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, cleanpath, &sbuf, &attributes ) ) { *targetcli = rootcli; pstrcpy( targetpath, path ); return True; } /* we got an error, check for DFS referral */ if ( !cli_dfs_check_error(rootcli) ) return False; /* check for the referral */ if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) ) return False; if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) || !num_refs ) { return False; } /* just store the first referral for now Make sure to recreate the original string including any wildcards */ make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); pathlen = strlen( fullpath )*2; consumed = MIN(pathlen, consumed ); pstrcpy( targetpath, &fullpath[consumed/2] ); split_dfs_path( refs[0].dfspath, server, share ); SAFE_FREE( refs ); /* open the connection to the target path */ if ( (*targetcli = cli_cm_open(server, share, False)) == NULL ) { d_printf("Unable to follow dfs referral [//%s/%s]\n", server, share ); return False; } /* parse out the consumed mount path */ /* trim off the \server\share\ */ fullpath[consumed/2] = '\0'; dos_clean_name( fullpath ); ppath = strchr_m( fullpath, '\\' ); ppath = strchr_m( ppath+1, '\\' ); ppath = strchr_m( ppath+1, '\\' ); ppath++; pstr_sprintf( newmount, "%s\\%s", mountpt, ppath ); cli_cm_set_mntpoint( *targetcli, newmount ); /* check for another dfs referral, note that we are not checking for loops here */ if ( !strequal( targetpath, "\\" ) ) { if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) { *targetcli = newcli; pstrcpy( targetpath, newpath ); } } return True; }