rm.c (ff2b18550948b1149db5d915293d7c25db25bba4) | rm.c (014a7923f9b48f6ab3ba1a38049a3dacddc587cb) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 4 unchanged lines hidden (view full) --- 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 4 unchanged lines hidden (view full) --- 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ |
21/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 22/* All Rights Reserved */ | |
23 | 21 |
24 | |
25/* 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 | 22/* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 |
27/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28/* All Rights Reserved */ 29 |
|
30#pragma ident "%Z%%M% %I% %E% SMI" 31 32/* 33 * rm [-fiRr] file ... 34 */ 35 36#include <stdio.h> 37#include <fcntl.h> 38#include <string.h> 39#include <sys/types.h> 40#include <sys/stat.h> 41#include <dirent.h> 42#include <limits.h> 43#include <locale.h> 44#include <langinfo.h> 45#include <unistd.h> 46#include <stdlib.h> 47#include <errno.h> 48#include <sys/resource.h> | 30#pragma ident "%Z%%M% %I% %E% SMI" 31 32/* 33 * rm [-fiRr] file ... 34 */ 35 36#include <stdio.h> 37#include <fcntl.h> 38#include <string.h> 39#include <sys/types.h> 40#include <sys/stat.h> 41#include <dirent.h> 42#include <limits.h> 43#include <locale.h> 44#include <langinfo.h> 45#include <unistd.h> 46#include <stdlib.h> 47#include <errno.h> 48#include <sys/resource.h> |
49#include <sys/avl.h> 50#include <libcmdutils.h> |
|
49 50#define ARGCNT 5 /* Number of arguments */ 51#define CHILD 0 52#define DIRECTORY ((buffer.st_mode&S_IFMT) == S_IFDIR) 53#define SYMLINK ((buffer.st_mode&S_IFMT) == S_IFLNK) 54#define FAIL -1 55#define MAXFORK 100 /* Maximum number of forking attempts */ 56#define NAMESIZE MAXNAMLEN + 1 /* "/" + (file name size) */ --- 25 unchanged lines hidden (view full) --- 82static void check_homedir(void); 83static void cleanup(void); 84 85static char *cwd; /* pathname of home dir, from getcwd() */ 86static rlim_t maxfiles; /* maximum number of open files */ 87static int first_dir = 1; /* flag set when first trying to remove a dir */ 88 /* flag set when can't get dev/inode of a parent dir */ 89static int parent_err = 0; | 51 52#define ARGCNT 5 /* Number of arguments */ 53#define CHILD 0 54#define DIRECTORY ((buffer.st_mode&S_IFMT) == S_IFDIR) 55#define SYMLINK ((buffer.st_mode&S_IFMT) == S_IFLNK) 56#define FAIL -1 57#define MAXFORK 100 /* Maximum number of forking attempts */ 58#define NAMESIZE MAXNAMLEN + 1 /* "/" + (file name size) */ --- 25 unchanged lines hidden (view full) --- 84static void check_homedir(void); 85static void cleanup(void); 86 87static char *cwd; /* pathname of home dir, from getcwd() */ 88static rlim_t maxfiles; /* maximum number of open files */ 89static int first_dir = 1; /* flag set when first trying to remove a dir */ 90 /* flag set when can't get dev/inode of a parent dir */ 91static int parent_err = 0; |
92static avl_tree_t *tree; /* tree to keep track of nodes visited */ |
|
90 91struct dir_id { 92 dev_t dev; 93 ino_t inode; 94 struct dir_id *next; 95}; 96 97 /* --- 65 unchanged lines hidden (view full) --- 163 164 if (getrlimit(RLIMIT_NOFILE, &rl)) { 165 perror("getrlimit"); 166 exit(2); 167 } else 168 maxfiles = rl.rlim_cur - 2; 169 170 while (argc-- > 0) { | 93 94struct dir_id { 95 dev_t dev; 96 ino_t inode; 97 struct dir_id *next; 98}; 99 100 /* --- 65 unchanged lines hidden (view full) --- 166 167 if (getrlimit(RLIMIT_NOFILE, &rl)) { 168 perror("getrlimit"); 169 exit(2); 170 } else 171 maxfiles = rl.rlim_cur - 2; 172 173 while (argc-- > 0) { |
174 tree = NULL; |
|
171 rm(*argv, 1); 172 argv++; | 175 rm(*argv, 1); 176 argv++; |
177 destroy_tree(tree); |
|
173 } | 178 } |
174 | |
175 cleanup(); 176 return (errcode ? 2 : 0); 177 /* NOTREACHED */ 178} 179 180static void 181rm(char *path, int first) 182{ --- 51 unchanged lines hidden (view full) --- 234 if (first_dir) { 235 check_homedir(); 236 first_dir = 0; 237 } 238 239 undir(path, first, buffer.st_dev, buffer.st_ino); 240 return; 241 } | 179 cleanup(); 180 return (errcode ? 2 : 0); 181 /* NOTREACHED */ 182} 183 184static void 185rm(char *path, int first) 186{ --- 51 unchanged lines hidden (view full) --- 238 if (first_dir) { 239 check_homedir(); 240 first_dir = 0; 241 } 242 243 undir(path, first, buffer.st_dev, buffer.st_ino); 244 return; 245 } |
242 | |
243 filepath = get_filename(path); 244 245 /* 246 * If interactive, ask for acknowledgement. 247 * 248 * TRANSLATION_NOTE - The following message will contain the 249 * first character of the strings for "yes" and "no" defined 250 * in the file "nl_langinfo.po". After substitution, the --- 73 unchanged lines hidden (view full) --- 324 325static void 326undir(char *path, int first, dev_t dev, ino_t ino) 327{ 328 char *newpath; 329 DIR *name; 330 struct dirent *direct; 331 int ismypath; | 246 filepath = get_filename(path); 247 248 /* 249 * If interactive, ask for acknowledgement. 250 * 251 * TRANSLATION_NOTE - The following message will contain the 252 * first character of the strings for "yes" and "no" defined 253 * in the file "nl_langinfo.po". After substitution, the --- 73 unchanged lines hidden (view full) --- 327 328static void 329undir(char *path, int first, dev_t dev, ino_t ino) 330{ 331 char *newpath; 332 DIR *name; 333 struct dirent *direct; 334 int ismypath; |
335 int ret; |
|
332 int chdir_failed = 0; 333 size_t len; 334 335 push_name(path, first); 336 337 /* 338 * If interactive and this file isn't in the path of the 339 * current working directory, ask for acknowledgement. --- 41 unchanged lines hidden (view full) --- 381 pop_name(first); 382 return; 383 } 384 } 385 } 386#endif 387 388 /* | 336 int chdir_failed = 0; 337 size_t len; 338 339 push_name(path, first); 340 341 /* 342 * If interactive and this file isn't in the path of the 343 * current working directory, ask for acknowledgement. --- 41 unchanged lines hidden (view full) --- 385 pop_name(first); 386 return; 387 } 388 } 389 } 390#endif 391 392 /* |
393 * Add this node to the search tree so we don't 394 * get into a endless loop. If the add fails then 395 * we have visited this node before. 396 */ 397 ret = add_tnode(&tree, dev, ino); 398 if (ret != 1) { 399 if (ret == 0) { 400 (void) fprintf(stderr, 401 gettext("rm: cycle detected for %s\n"), 402 fullpath); 403 } else if (ret == -1) { 404 perror("rm"); 405 } 406 errcode++; 407 pop_name(first); 408 return; 409 } 410 411 /* |
|
389 * Open the directory for reading. 390 */ 391 if ((name = opendir(path)) == NULL) { 392 int saveerrno = errno; 393 394 /* 395 * If interactive, ask for acknowledgement. 396 */ --- 316 unchanged lines hidden (view full) --- 713 } 714 curlen = strlen(fullpath); 715} 716 717static void 718pop_name(int first) 719{ 720 char *slash; | 412 * Open the directory for reading. 413 */ 414 if ((name = opendir(path)) == NULL) { 415 int saveerrno = errno; 416 417 /* 418 * If interactive, ask for acknowledgement. 419 */ --- 316 unchanged lines hidden (view full) --- 736 } 737 curlen = strlen(fullpath); 738} 739 740static void 741pop_name(int first) 742{ 743 char *slash; |
721 | |
722 if (first) { 723 *fullpath = '\0'; 724 return; 725 } 726 slash = strrchr(fullpath, '/'); 727 if (slash) 728 *slash = '\0'; 729 else --- 206 unchanged lines hidden (view full) --- 936/* 937 * cleanup the dynamically-allocated list of device numbers and inodes, 938 * if any. If homedir was never used, it is external and static so 939 * it is guaranteed initialized to zero, thus homedir.next would be NULL. 940 */ 941 942static void 943cleanup(void) { | 744 if (first) { 745 *fullpath = '\0'; 746 return; 747 } 748 slash = strrchr(fullpath, '/'); 749 if (slash) 750 *slash = '\0'; 751 else --- 206 unchanged lines hidden (view full) --- 958/* 959 * cleanup the dynamically-allocated list of device numbers and inodes, 960 * if any. If homedir was never used, it is external and static so 961 * it is guaranteed initialized to zero, thus homedir.next would be NULL. 962 */ 963 964static void 965cleanup(void) { |
944 | |
945 struct dir_id *lastdir, *curdir; 946 947 curdir = homedir.next; 948 949 while (curdir != NULL) { 950 lastdir = curdir; 951 curdir = curdir->next; 952 free(lastdir); 953 } 954} | 966 struct dir_id *lastdir, *curdir; 967 968 curdir = homedir.next; 969 970 while (curdir != NULL) { 971 lastdir = curdir; 972 curdir = curdir->next; 973 free(lastdir); 974 } 975} |