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 //%% $TOG: remover.C /main/5 1999/10/14 18:37:42 mgreess $
29 * remover.cc - ToolTalk wrapper for rm(1) and rmdir(1).
31 * Copyright (c) 1990 by Sun Microsystems, Inc.
35 #include "tt_options.h"
38 #if defined(__osf__) || defined(linux) || defined(CSRG_BASED)
41 #if !defined(USL) && !defined(__uxp__)
48 #include <sys/inode.h>
49 #define S_ISLNK(m) (((m)&IFMT) == IFLNK)
52 #if defined(OPT_BUG_USL) || defined(OPT_BUG_UXP)
53 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
56 #include "api/c/tt_c.h"
57 #include "util/tt_path.h"
58 #include "util/tt_gettext.h"
59 #include "util/copyright.h"
73 char *base = strrchr( arg0, '/' );
80 _process_name = _prog_name;
82 _am_rmdir = (_prog_name == "ttrmdir");
83 _args = new _Tt_string_list();
84 _paths = new _Tt_string_list();
97 * remover::do_rm() - Invoke rm[dir](1), and return its exit status.
98 * We can just use _args, since we never get here when our one
99 * incompatible option (-L) has been given.
105 _Tt_string_list_cursor arg_cursor( _args );
112 while (arg_cursor.next()) {
113 cmd = cmd.cat( " " ).cat( *arg_cursor );
115 //printf( "Invoking: %s\n", (char *)cmd );
116 int sys_status = system( (char *)cmd );
117 if (WIFEXITED(sys_status)) {
118 return WEXITSTATUS(sys_status);
121 "%s: system(\"%s\"): %d\n",
122 (char *)_process_name, (char *)cmd, sys_status );
128 * remover::do_ttrm() - Use tt_file_destroy() on the paths to destroy.
133 return this->_ttrm_paths( _paths );
137 * remover::ttrm_path() - tt_file_destroy() this path.
140 _ttrm_paths( _Tt_string_list_ptr paths )
142 Tt_status worst_err = TT_OK;
144 bool_t abort = FALSE;
146 while ((! paths->is_empty()) && (! abort)) {
147 _Tt_string path = paths->top();
148 _Tt_string_list_ptr children;
151 if (! this->can_rm( path )) {
155 _Tt_string_list_ptr children = _tt_dir_entries(path,
157 err = this->_ttrm_paths( children );
158 if (err > TT_WRN_LAST) {
172 err = tt_file_destroy( (char *)path );
173 if (err > TT_WRN_LAST) {
177 catgets(_ttcatd, 8, 7,
178 "%s: Could not remove "
179 "ToolTalk objects of "
181 (char *)_process_name,
183 tt_status_message(err) );
203 * remover::can_rm() - Can we remove this path?
205 * TO_DO: For now I'll count on tt_file_destroy() not to let me
206 * destroy the specs in files I can't remove.
209 can_rm( _Tt_string path )
214 struct stat lstat_buf;
216 if (lstat( (char *)path, &lstat_buf) == 0) {
217 if (S_ISDIR(lstat_buf.st_mode)) {
219 * rm(1) without the -r flag
220 * won't remove directories,
221 * but tt_file_destroy() will,
222 * so we make sure not to ask
226 fprintf( stderr, "%s: %s: %s\n",
232 } else if (S_ISLNK(lstat_buf.st_mode)) {
234 * Don't tt_file_destroy() a symlink,
235 * or TT will tt_file_destroy() the
256 char *process_id = tt_open();
257 Tt_status err = tt_ptr_error( process_id );
259 _process_id = process_id;
261 } else if (err > TT_WRN_LAST) {
263 "%s: tt_open(): %s\n",
264 (char *)_process_name, tt_status_message(err) );
270 * remover::close_tt()
278 Tt_status err = tt_close();
279 if (err > TT_WRN_LAST) {
281 "%s: tt_close(): %s\n",
282 (char *)_process_name, tt_status_message(err) );
288 * remover::parse_args()
291 parse_args( int argc, char **argv )
293 bool_t no_more_options = FALSE;
295 for ( int arg_num = 1; arg_num < argc; arg_num++ ) {
296 _Tt_string arg( argv[arg_num] );
297 _args->append( arg );
300 this->_parse_arg( (char *)arg );
302 _paths->append( arg );
305 if ((arg[0] != '-') || no_more_options) {
306 _paths->append( arg );
308 if (arg[1] == '\0') {
310 * The bare option "-" means take the
311 * subsequent arguments to be paths.
313 no_more_options = TRUE;
315 this->_parse_arg( (char *)arg );
320 if (_paths->count() <= 0) {
327 * remover::_parse_arg() - Parse an option
330 _parse_arg( char *arg )
336 while (arg[++n] != '\0') {
365 _TT_PRINT_VERSIONS((char *)_prog_name)
380 usage(FILE *fs) const
383 catgets(_ttcatd, 8, 8,
384 "Usage: %s [-] [-%s] %s ...\n"
388 (_am_rmdir ? "L" : "fLrR"),
389 (_am_rmdir ? catgets(_ttcatd, 8, 9, "file")
390 : catgets(_ttcatd, 8, 10, "dir") ),
391 (char *)_prog_name, (char *)_prog_name );
393 catgets(_ttcatd, 8, 11,
394 "\t-L do not perform a %s(1)\n"
395 "\t-v print the version number and quit\n"
396 "\t-h[elp] print this message\n" ),
397 (_am_rmdir ? "rmdir" : "rm"));