2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
24 //%% (c) Copyright 1993, 1994 International Business Machines Corp.
25 //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
26 //%% (c) Copyright 1993, 1994 Novell, Inc.
27 //%% $XConsortium: rcopier.C /main/3 1995/10/20 16:36:32 rswiston $
29 * rcopier.cc - Link Service/ToolTalk wrapper for rcp(1).
31 * Copyright (c) 1990 by Sun Microsystems, Inc.
35 #include "tt_options.h"
44 #if defined(OPT_BUG_SUNOS_4)
47 #include <api/c/tt_c.h>
48 #include <util/tt_path.h>
49 #include <util/tt_enumname.h>
50 #include <util/copyright.h>
57 implement_list_of(rpath)
94 char *base = strrchr( arg0, '/' );
98 base++; /* Don't want the '/' */
101 _process_name = _prog_name;
103 _args = new _Tt_string_list();
104 _from_paths = new rpath_list();
117 * rcopier::do_rcp() - Use system() to invoke rcp(1), and return its exit status.
118 * We can just use _args, since we never get here when our one
119 * rcp-incompatible option (-L) has been given.
124 _Tt_string cmd( "rcp" );
125 _Tt_string_list_cursor arg_cursor( _args );
127 while (arg_cursor.next()) {
128 cmd = cmd.cat( " " ).cat( *arg_cursor );
130 printf( "Invoking: %s\n", (char *)cmd );
131 int sys_status = system( (char *)cmd );
132 if (WIFEXITED(sys_status)) {
133 return WEXITSTATUS(sys_status);
136 "%s: I invoked rcp(1), but system() returned "
137 "%d, which is not an exit status!\n",
138 (char *)_process_name, sys_status );
144 * rcopier::do_ttrcp() - Use tttar(1) to copy the objects of the _from_paths.
148 * [rsh fromhost -l user] tttar cfhL - frompath |
149 * [rsh tohost -l user] tttar xfL - -rename frompath topath
151 * TO_DO: this won't work if topath is a directory. If it's a
152 * remote directory, how do we find this out?
158 rpath_list_cursor from_path_cursor( _from_paths );
161 * TO_DO: tt_file_destroy() any paths that rcp(1) will delete
163 while (from_path_cursor.next()) {
165 rpath_ptr rp = *from_path_cursor;
167 if (rp->host().len() >= 0) {
168 cmd = cmd.cat( "rsh ").cat( rp->host()).cat( " -l ")
169 .cat( _username ).cat( " " );
171 cmd = cmd.cat( "tttar cfhL - " ).cat( rp->path()).cat(" | ");
172 if (_to_path->host().len() >= 0) {
173 cmd = cmd.cat( "rsh ").cat( _to_path->host())
174 .cat( " -l ").cat( _username ).cat( " " );
176 cmd = cmd.cat( "tttar xfL" );
178 cmd = cmd.cat( "p" );
180 cmd = cmd.cat( " - -rename " ).cat( rp->path())
181 .cat( _to_path->path());
182 printf( "Invoking: %s\n", (char *)cmd );
183 int sys_status = system( (char *)cmd );
184 if (WIFEXITED(sys_status)) {
185 if (WEXITSTATUS(sys_status) != 0) {
186 return TT_ERR_INTERNAL;
190 "%s: invoked tttar(1), but system() returned "
191 "%d, which is not an exit status!\n",
192 (char *)_process_name, sys_status );
193 return TT_ERR_INTERNAL;
206 char *process_id = tt_open();
207 Tt_status err = tt_ptr_error( process_id );
209 _process_id = process_id;
211 } else if (err > TT_WRN_LAST) {
213 "%s: Could not initialize ToolTalk because %s\n",
214 (char *)_process_name,
215 #ifndef TT_STATUS_MSG_TO_DO
216 _tt_enumname( (Tt_status)err )
218 tt_status_message( err )
226 * rcopier::close_tt()
234 Tt_status err = tt_close();
235 if (err > TT_WRN_LAST) {
237 "%s: Could not close ToolTalk because %s\n",
238 (char *)_process_name,
239 #ifndef TT_STATUS_MSG_TO_DO
240 _tt_enumname( (Tt_status)err )
242 tt_status_message( err )
250 * rcopier::parse_args()
253 parse_args( int argc, char **argv )
255 for ( int arg_num = 1; arg_num < argc; arg_num++ ) {
256 _Tt_string arg( argv[arg_num] );
257 _args->append( arg );
259 this->_parse_arg( (char *)arg );
261 if (arg_num == argc - 1) {
262 _to_path = new rpath( arg );
264 rpath_ptr rp = new rpath( arg );
265 _from_paths->append( rp );
269 if (_to_path->path().len() <= 0) {
273 if (_from_paths->count() <= 0) {
277 if (_from_paths->count() > 1) {
279 * If multiple things to move, the place we're
280 * moving them to must be a directory.
282 if (_to_path->host().len() <= 0) {
284 * to_path is local. Yay!
286 struct stat stat_buf;
288 if (stat( (char *)_to_path->path(), &stat_buf) != 0) {
289 fprintf( stderr, "%s: %s: ",
290 (char *)_process_name,
291 (char *)_to_path->path() );
295 if (! S_ISDIR(stat_buf.st_mode)) {
296 fprintf( stderr, "%s: %s is not a directory\n",
297 (char *)_process_name,
298 (char *)_to_path->path() );
302 _to_path_is_dir = TRUE;
305 * TO_DO: figure out if remote path is dir or not
309 if (_to_path->host().len() <= 0) {
310 struct stat stat_buf;
312 _to_path_is_dir = FALSE;
313 if (stat( (char *)_to_path->path(), &stat_buf) == 0) {
314 _to_path_is_dir = S_ISDIR(stat_buf.st_mode);
317 * I don't think rcp has a clonedir mode. (see ttcp)
319 _Tt_string from_path = _from_paths->top();
320 if ( (_from_paths->count() == 1)
321 && (stat( (char *)from_path, &stat_buf) == 0)
322 && S_ISDIR(stat_buf.st_mode))
324 _clonedir_mode = TRUE;
325 _to_path_is_dir = TRUE;
331 * TO_DO: figure out if remote path is dir or not
339 * rcopier::_parse_arg() - Parse an option
342 _parse_arg( char *arg )
348 while (arg[++n] != '\0') {
366 _TT_PRINT_VERSIONS((char *)_prog_name)
381 usage(FILE *fs) const
384 "Usage: %s [-pL] file1 file2\n"
385 " %s [-prL] path1 [path2 ...] dir\n"
388 (char *)_prog_name, (char *)_prog_name, (char *)_prog_name,
389 (char *)_prog_name );
390 fprintf( fs, "\t-L do not perform a rcp(1)\n" );
391 fprintf( fs, "\t-v print the version number and quit\n" );
392 fprintf( fs, "\t-h[elp] print this message\n" );