static void rm_file(char **argv) { struct stat sb; int rval; char *f; /* * Remove a file. POSIX 1003.2 states that, by default, attempting * to remove a directory is an error, so must always stat the file. */ while ((f = *argv++) != NULL) { /* Assume if can't stat the file, can't unlink it. */ if (lstat(f, &sb)) { if (Wflag) { sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR; } else { if (!fflag || !NONEXISTENT(errno)) { warn("%s", f); eval = 1; } continue; } } else if (Wflag) { warnx("%s: %s", f, strerror(EEXIST)); eval = 1; continue; } if (S_ISDIR(sb.st_mode) && !dflag) { warnx("%s: is a directory", f); eval = 1; continue; } if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb)) continue; if (S_ISWHT(sb.st_mode)) #ifdef HAVE_FUNC1_UNDELETE_UNISTD_H rval = undelete(f); #else rval = EPERM; #endif else if (S_ISDIR(sb.st_mode)) rval = rmdir(f); else { if (Pflag) { if (rm_overwrite(f, &sb)) continue; } rval = unlink(f); } if (rval && (!fflag || !NONEXISTENT(errno))) { warn("%s", f); eval = 1; } if (vflag && rval == 0) (void)printf("%s\n", f); }
static int readdir_r_wrapper(DIR *dirp, struct dirent *entry, struct dirent **result) { if (dirp -> __dd_fd < 0) { DIR_wrapper *t_wrapper; t_wrapper = (DIR_wrapper *)dirp; if (t_wrapper -> index == t_wrapper -> entry_count) { *result = nil; return 0; } char *t_item_path; MCCStringFormat(t_item_path, "%s/%s", s_redirect_base, t_wrapper -> entries[t_wrapper -> index]); struct stat t_stat; lstat(t_item_path, &t_stat); MCCStringFree(t_item_path); entry -> d_fileno = t_stat . st_ino; if (S_ISBLK(t_stat . st_mode)) entry -> d_type = DT_BLK; else if (S_ISCHR(t_stat . st_mode)) entry -> d_type = DT_CHR; else if (S_ISDIR(t_stat . st_mode)) entry -> d_type = DT_DIR; else if (S_ISFIFO(t_stat . st_mode)) entry -> d_type = DT_FIFO; else if (S_ISREG(t_stat . st_mode)) entry -> d_type = DT_REG; else if (S_ISLNK(t_stat . st_mode)) entry -> d_type = DT_LNK; else if (S_ISSOCK(t_stat . st_mode)) entry -> d_type = DT_SOCK; else if (S_ISWHT(t_stat . st_mode)) entry -> d_type = DT_WHT; else entry -> d_type = DT_UNKNOWN; strcpy(entry -> d_name, t_wrapper -> entries[t_wrapper -> index]); entry -> d_reclen = sizeof(struct dirent) - sizeof(entry -> d_name) + ((strlen(entry -> d_name) + 4) & ~3); t_wrapper -> index += 1; *result = entry; return 0; } return readdir_r_trampoline(dirp, entry, result); }
static char ftypelet (mode_t bits) { if (S_ISBLK (bits)) return 'b'; if (S_ISCHR (bits)) return 'c'; if (S_ISDIR (bits)) return 'd'; if (S_ISREG (bits)) return '-'; if (S_ISFIFO (bits)) return 'p'; if (S_ISLNK (bits)) return 'l'; if (S_ISSOCK (bits)) return 's'; if (S_ISMPC (bits)) return 'm'; if (S_ISNWK (bits)) return 'n'; if (S_ISDOOR (bits)) return 'D'; if (S_ISCTG (bits)) return 'C'; /* Added by Alexander Lamaison for Swish project */ if (S_ISWHT (bits)) return 'w'; if (S_ISMPB (bits)) return 'B'; if (S_ISNAM (bits)) return 'x'; /* Added 2006.08.20 */ /* The following two tests are for Cray DMF (Data Migration Facility), which is a HSM file system. A migrated file has a `st_dm_mode' that is different from the normal `st_mode', so any tests for migrated files should use the former. */ if (S_ISOFD (bits)) /* off line, with data */ return 'M'; /* off line, with no data */ if (S_ISOFL (bits)) return 'M'; return '?'; }
static char filetype(mode_t mode) { /* common cases first */ if (S_ISREG(mode)) return '-'; if (S_ISDIR(mode)) return 'd'; if (S_ISLNK(mode)) return 'l'; /* special files */ if (S_ISBLK(mode)) return 'b'; if (S_ISCHR(mode)) return 'c'; if (S_ISFIFO(mode)) return 'p'; if (S_ISSOCK(mode)) return 's'; /* non-standard types */ if (S_ISDOOR(mode)) return 'D'; if (S_ISPORT(mode)) return 'P'; if (S_ISWHT(mode)) return 'w'; /* unknown */ return '?'; }
static char ftypelet (mode_t bits) { /* These are the most common, so test for them first. */ if (S_ISREG (bits)) return '-'; if (S_ISDIR (bits)) return 'd'; /* Other letters standardized by POSIX 1003.1-2004. */ if (S_ISBLK (bits)) return 'b'; if (S_ISCHR (bits)) return 'c'; if (S_ISLNK (bits)) return 'l'; if (S_ISFIFO (bits)) return 'p'; /* Other file types (though not letters) standardized by POSIX. */ if (S_ISSOCK (bits)) return 's'; /* Nonstandard file types. */ if (S_ISCTG (bits)) return 'C'; if (S_ISDOOR (bits)) return 'D'; if (S_ISMPB (bits) || S_ISMPC (bits) || S_ISMPX (bits)) return 'm'; if (S_ISNWK (bits)) return 'n'; if (S_ISPORT (bits)) return 'P'; if (S_ISWHT (bits)) return 'w'; return '?'; }
/* * Add a + after the standard rwxrwxrwx mode if the file has an * ACL. strmode() reserves space at the end of the string. */ static void aclmode(char *buf, const FTSENT *p) { char name[MAXPATHLEN + 1]; int ret, trivial; static dev_t previous_dev = NODEV; static int supports_acls = -1; static int type = ACL_TYPE_ACCESS; acl_t facl; /* * XXX: ACLs are not supported on whiteouts and device files * residing on UFS. */ if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) || S_ISWHT(p->fts_statp->st_mode)) return; if (previous_dev == p->fts_statp->st_dev && supports_acls == 0) return; if (p->fts_level == FTS_ROOTLEVEL) snprintf(name, sizeof(name), "%s", p->fts_name); else snprintf(name, sizeof(name), "%s/%s", p->fts_parent->fts_accpath, p->fts_name); if (previous_dev != p->fts_statp->st_dev) { previous_dev = p->fts_statp->st_dev; supports_acls = 0; ret = lpathconf(name, _PC_ACL_NFS4); if (ret > 0) { type = ACL_TYPE_NFS4; supports_acls = 1; } else if (ret < 0 && errno != EINVAL) { xo_warn("%s", name); return; } if (supports_acls == 0) { ret = lpathconf(name, _PC_ACL_EXTENDED); if (ret > 0) { type = ACL_TYPE_ACCESS; supports_acls = 1; } else if (ret < 0 && errno != EINVAL) { xo_warn("%s", name); return; } } } if (supports_acls == 0) return; facl = acl_get_link_np(name, type); if (facl == NULL) { xo_warn("%s", name); return; } if (acl_is_trivial_np(facl, &trivial)) { acl_free(facl); xo_warn("%s", name); return; } if (!trivial) buf[10] = '+'; acl_free(facl); }
void printlong(const DISPLAY *dp) { struct stat *sp; FTSENT *p; NAMES *np; char buf[20]; #ifdef COLORLS int color_printed = 0; #endif if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) && (f_longform || f_size)) { xo_emit("{L:total} {:total-blocks/%lu}\n", howmany(dp->btotal, blocksize)); } xo_open_list("entry"); for (p = dp->list; p; p = p->fts_link) { char *name, *type; if (IS_NOPRINT(p)) continue; xo_open_instance("entry"); sp = p->fts_statp; name = getname(p->fts_name); if (name) xo_emit("{ke:name/%hs}", name); if (f_inode) xo_emit("{t:inode/%*ju} ", dp->s_inode, (uintmax_t)sp->st_ino); if (f_size) xo_emit("{t:blocks/%*jd} ", dp->s_block, howmany(sp->st_blocks, blocksize)); strmode(sp->st_mode, buf); aclmode(buf, p); np = p->fts_pointer; xo_attr("value", "%03o", (int) sp->st_mode & ALLPERMS); if (f_numericonly) { xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {td:user/%-*s}{e:user/%ju} {td:group/%-*s}{e:group/%ju} ", buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink, dp->s_user, np->user, sp->st_uid, dp->s_group, np->group, sp->st_gid); } else { xo_emit("{t:mode/%s}{e:mode_octal/%03o} {t:links/%*u} {t:user/%-*s} {t:group/%-*s} ", buf, (int) sp->st_mode & ALLPERMS, dp->s_nlink, sp->st_nlink, dp->s_user, np->user, dp->s_group, np->group); } if (S_ISBLK(sp->st_mode)) asprintf(&type, "block"); if (S_ISCHR(sp->st_mode)) asprintf(&type, "character"); if (S_ISDIR(sp->st_mode)) asprintf(&type, "directory"); if (S_ISFIFO(sp->st_mode)) asprintf(&type, "fifo"); if (S_ISLNK(sp->st_mode)) asprintf(&type, "symlink"); if (S_ISREG(sp->st_mode)) asprintf(&type, "regular"); if (S_ISSOCK(sp->st_mode)) asprintf(&type, "socket"); if (S_ISWHT(sp->st_mode)) asprintf(&type, "whiteout"); xo_emit("{e:type/%s}", type); free(type); if (f_flags) xo_emit("{:flags/%-*s} ", dp->s_flags, np->flags); if (f_label) xo_emit("{t:label/%-*s} ", dp->s_label, np->label); if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode)) printdev(dp->s_size, sp->st_rdev); else printsize("size", dp->s_size, sp->st_size); if (f_accesstime) printtime("access-time", sp->st_atime); else if (f_birthtime) printtime("birth-time", sp->st_birthtime); else if (f_statustime) printtime("change-time", sp->st_ctime); else printtime("modify-time", sp->st_mtime); #ifdef COLORLS if (f_color) color_printed = colortype(sp->st_mode); #endif if (name) { xo_emit("{dk:name/%hs}", name); free(name); } #ifdef COLORLS if (f_color && color_printed) endcolor(0); #endif if (f_type) (void)printtype(sp->st_mode); if (S_ISLNK(sp->st_mode)) printlink(p); xo_close_instance("entry"); xo_emit("\n"); } xo_close_list("entry"); }
S_ISCHR (S_IFREG), S_ISDIR (S_IFREG), S_ISFIFO (S_IFREG), S_ISREG (S_IFREG), S_ISLNK (S_IFREG), S_ISSOCK (S_IFREG), S_ISDOOR (S_IFREG), S_ISMPB (S_IFREG), S_ISMPX (S_IFREG), S_ISNAM (S_IFREG), S_ISNWK (S_IFREG), S_ISPORT (S_IFREG), S_ISCTG (S_IFREG), S_ISOFD (S_IFREG), S_ISOFL (S_IFREG), S_ISWHT (S_IFREG) }; /* Sanity checks. */ verify (S_IRWXU == (S_IRUSR | S_IWUSR | S_IXUSR)); verify (S_IRWXG == (S_IRGRP | S_IWGRP | S_IXGRP)); verify (S_IRWXO == (S_IROTH | S_IWOTH | S_IXOTH)); #ifdef S_IFBLK verify (S_ISBLK (S_IFBLK)); #endif verify (!S_ISBLK (S_IFCHR)); verify (!S_ISBLK (S_IFDIR)); verify (!S_ISBLK (S_IFIFO)); verify (!S_ISBLK (S_IFREG));
static void rm_file(char **argv) { struct stat sb; int rval; char *f; /* * Remove a file. POSIX 1003.2 states that, by default, attempting * to remove a directory is an error, so must always stat the file. */ while ((f = *argv++) != NULL) { /* Assume if can't stat the file, can't unlink it. */ if (lstat(f, &sb)) { if (Wflag) { sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR; } else { if (!fflag || errno != ENOENT) { warn("%s", f); eval = 1; } continue; } } else if (Wflag) { warnx("%s: %s", f, strerror(EEXIST)); eval = 1; continue; } if (S_ISDIR(sb.st_mode) && !dflag) { warnx("%s: is a directory", f); eval = 1; continue; } if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb)) continue; rval = 0; if (!uid && !S_ISWHT(sb.st_mode) && (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE))) rval = lchflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE)); if (rval == 0) { if (S_ISWHT(sb.st_mode)) rval = undelete(f); else if (S_ISDIR(sb.st_mode)) rval = rmdir(f); else { if (Pflag) if (!rm_overwrite(f, &sb)) continue; rval = unlink(f); } } if (rval && (!fflag || errno != ENOENT)) { warn("%s", f); eval = 1; } if (vflag && rval == 0) (void)printf("%s\n", f); if (info && rval == 0) { info = 0; (void)printf("%s\n", f); } } }
void record_stat( struct stat * statp, char * path_name ) { struct file_info * node_ptr = file_info_list_head; struct file_info * new_node = malloc (sizeof(struct file_info)); struct passwd * password; struct group * group; /* initialize the new node */ new_node->file_type = ' '; new_node->next = NULL; /* assign file stat info into file_info structure */ /* get file's file serial number (inode number) */ new_node->inode_number = statp->st_ino; /* get file type and permissons */ strmode ( statp->st_mode, new_node->type_permission_info ); /* get file type */ if ( S_ISDIR ( statp->st_mode ) ) new_node->file_type = '/'; else if ( S_ISLNK ( statp->st_mode ) ) new_node->file_type = '@'; else if (!access ( path_name, X_OK )) /* executable file */ new_node->file_type = '*'; #ifdef S_ISWHT else if ( S_ISWHT (statp->st_mode) ) new_node->file_type = '%'; #endif else if ( S_ISSOCK ( statp->st_mode ) ) new_node->file_type = '='; else if ( S_ISFIFO ( statp->st_mode ) ) new_node->file_type = '|'; /* get file number of links */ new_node->number_of_links = statp->st_nlink; /* get file owner */ new_node->user_id = statp->st_uid; password = getpwuid ( statp->st_uid ); strcpy ( new_node->owner_name, password->pw_name ); /* get file group owner */ new_node->group_id = statp->st_gid; group = getgrgid ( statp->st_gid ); strcpy ( new_node->group_name, group->gr_name ); /* get number of bytes */ new_node->number_of_bytes = statp->st_size; /* get last access time */ strftime ( new_node->last_access_time, sizeof(new_node->last_access_time), "%b %d %R", localtime ( & statp->st_atime ) ); new_node->a_time = statp->st_atime; /* get last modified time */ strftime ( new_node->last_modi_time, sizeof(new_node->last_modi_time), "%b %d %R", localtime ( &statp->st_mtime ) ); new_node->m_time = statp->st_mtime; /* get last change time */ strftime ( new_node->last_change_time, sizeof(new_node->last_change_time), "%b %d %R", localtime ( &statp->st_ctime ) ); new_node->c_time = statp->st_ctime; /* get file path name */ if ( isatty (1) || f_q_option ) { /* output is to a terminal or -q is set, then force printing of non-printable characters in file name as the character '?' */ char str [255]; char * ptr; strcpy ( str, path_name ); ptr = &str[0]; while ( *ptr != '\0' ) { if ( isprint(*ptr) == 0 ) { *ptr = '?'; } ptr ++; } strcpy ( new_node->path_name, str ); } else strcpy ( new_node->path_name, path_name ); /* get number of file system blocks actually used */ char * blocksize_str; char * blocksize_constant = "BLOCKSIZE"; unsigned long long blocksize = 0; unsigned long long n = 0; blocksize_str = getenv ( blocksize_constant ); if ( NULL == blocksize_str ) { /* ENV BLOCKSIZE is not set, so use default value */ new_node->number_of_blocks = statp->st_blocks; } else { blocksize = strtoll ( blocksize_str, NULL, 0 ); n = blocksize / 512; if ( n == 1 ) new_node->number_of_blocks = statp->st_blocks; else new_node->number_of_blocks = statp->st_blocks / n; } /* add new node into list */ if ( node_ptr == NULL ) file_info_list_head = new_node; else { while ( node_ptr->next != NULL ) { node_ptr = node_ptr->next; } node_ptr->next = new_node; } }
char const * file_type (struct stat const *st) { /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107 for some of these formats. To keep diagnostics grammatical in English, the returned string must start with a consonant. */ /* Do these three first, as they're the most common. */ if (S_ISREG (st->st_mode)) return st->st_size == 0 ? _("regular empty file") : _("regular file"); if (S_ISDIR (st->st_mode)) return _("directory"); if (S_ISLNK (st->st_mode)) return _("symbolic link"); /* Do the S_TYPEIS* macros next, as they may be implemented in terms of S_ISNAM, and we want the more-specialized interpretation. */ if (S_TYPEISMQ (st)) return _("message queue"); if (S_TYPEISSEM (st)) return _("semaphore"); if (S_TYPEISSHM (st)) return _("shared memory object"); if (S_TYPEISTMO (st)) return _("typed memory object"); /* The remaining are in alphabetical order. */ if (S_ISBLK (st->st_mode)) return _("block special file"); if (S_ISCHR (st->st_mode)) return _("character special file"); if (S_ISCTG (st->st_mode)) return _("contiguous data"); if (S_ISFIFO (st->st_mode)) return _("fifo"); if (S_ISDOOR (st->st_mode)) return _("door"); if (S_ISMPB (st->st_mode)) return _("multiplexed block special file"); if (S_ISMPC (st->st_mode)) return _("multiplexed character special file"); if (S_ISMPX (st->st_mode)) return _("multiplexed file"); if (S_ISNAM (st->st_mode)) return _("named file"); if (S_ISNWK (st->st_mode)) return _("network special file"); if (S_ISOFD (st->st_mode)) return _("migrated file with data"); if (S_ISOFL (st->st_mode)) return _("migrated file without data"); if (S_ISPORT (st->st_mode)) return _("port"); if (S_ISSOCK (st->st_mode)) return _("socket"); if (S_ISWHT (st->st_mode)) return _("whiteout"); return _("weird file"); }
static int make_fileinfo(FILE *out, const char *filename, struct fileinfo *file, int flags) { char buf[128]; int file_type = 0; struct stat *st = &file->st; file->inode = st->st_ino; file->bsize = block_convert(st->st_blocks); if(S_ISDIR(st->st_mode)) { file->mode[0] = 'd'; file_type = '/'; } else if(S_ISCHR(st->st_mode)) file->mode[0] = 'c'; else if(S_ISBLK(st->st_mode)) file->mode[0] = 'b'; else if(S_ISREG(st->st_mode)) { file->mode[0] = '-'; if(st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) file_type = '*'; } else if(S_ISFIFO(st->st_mode)) { file->mode[0] = 'p'; file_type = '|'; } else if(S_ISLNK(st->st_mode)) { file->mode[0] = 'l'; file_type = '@'; } else if(S_ISSOCK(st->st_mode)) { file->mode[0] = 's'; file_type = '='; } #ifdef S_ISWHT else if(S_ISWHT(st->st_mode)) { file->mode[0] = 'w'; file_type = '%'; } #endif else file->mode[0] = '?'; { char *x[] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" }; strcpy(file->mode + 1, x[(st->st_mode & S_IRWXU) >> 6]); strcpy(file->mode + 4, x[(st->st_mode & S_IRWXG) >> 3]); strcpy(file->mode + 7, x[(st->st_mode & S_IRWXO) >> 0]); if((st->st_mode & S_ISUID)) { if((st->st_mode & S_IXUSR)) file->mode[3] = 's'; else file->mode[3] = 'S'; } if((st->st_mode & S_ISGID)) { if((st->st_mode & S_IXGRP)) file->mode[6] = 's'; else file->mode[6] = 'S'; } if((st->st_mode & S_ISTXT)) { if((st->st_mode & S_IXOTH)) file->mode[9] = 't'; else file->mode[9] = 'T'; } } file->n_link = st->st_nlink; { struct passwd *pwd; pwd = getpwuid(st->st_uid); if(pwd == NULL) { if (asprintf(&file->user, "%u", (unsigned)st->st_uid) == -1) file->user = NULL; } else file->user = strdup(pwd->pw_name); if (file->user == NULL) { syslog(LOG_ERR, "out of memory"); return -1; } } { struct group *grp; grp = getgrgid(st->st_gid); if(grp == NULL) { if (asprintf(&file->group, "%u", (unsigned)st->st_gid) == -1) file->group = NULL; } else file->group = strdup(grp->gr_name); if (file->group == NULL) { syslog(LOG_ERR, "out of memory"); return -1; } } if(S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) { #if defined(major) && defined(minor) if (asprintf(&file->major, "%u", (unsigned)major(st->st_rdev)) == -1) file->major = NULL; if (asprintf(&file->minor, "%u", (unsigned)minor(st->st_rdev)) == -1) file->minor = NULL; #else /* Don't want to use the DDI/DKI crap. */ if (asprintf(&file->major, "%u", (unsigned)st->st_rdev) == -1) file->major = NULL; if (asprintf(&file->minor, "%u", 0) == -1) file->minor = NULL; #endif if (file->major == NULL || file->minor == NULL) { syslog(LOG_ERR, "out of memory"); return -1; } } else { if (asprintf(&file->size, "%lu", (unsigned long)st->st_size) == -1) file->size = NULL; } { time_t t = time(NULL); time_t mtime = st->st_mtime; struct tm *tm = localtime(&mtime); if((t - mtime > 6*30*24*60*60) || (mtime - t > 6*30*24*60*60)) strftime(buf, sizeof(buf), "%b %e %Y", tm); else strftime(buf, sizeof(buf), "%b %e %H:%M", tm); file->date = strdup(buf); if (file->date == NULL) { syslog(LOG_ERR, "out of memory"); return -1; } } { const char *p = strrchr(filename, '/'); if(p) p++; else p = filename; if((flags & LS_TYPE) && file_type != 0) { if (asprintf(&file->filename, "%s%c", p, file_type) == -1) file->filename = NULL; } else file->filename = strdup(p); if (file->filename == NULL) { syslog(LOG_ERR, "out of memory"); return -1; } } if(S_ISLNK(st->st_mode)) { int n; n = readlink((char *)filename, buf, sizeof(buf) - 1); if(n >= 0) { buf[n] = '\0'; file->link = strdup(buf); if (file->link == NULL) { syslog(LOG_ERR, "out of memory"); return -1; } } else sec_fprintf2(out, "readlink(%s): %s", filename, strerror(errno)); } return 0; }
static int rm_file(char **argv) { struct stat sb; int rval; char *f; /* * Check up front before anything is deleted. */ int i; for (i = 0; argv[i]; i++) { if (kBuildProtectionEnforce(&g_ProtData, KBUILDPROTECTIONTYPE_FULL, argv[i])) return 1; } /* * Remove a file. POSIX 1003.2 states that, by default, attempting * to remove a directory is an error, so must always stat the file. */ while ((f = *argv++) != NULL) { const char *operation = "?"; /* Assume if can't stat the file, can't unlink it. */ if (lstat(f, &sb)) { #ifdef FTS_WHITEOUT if (Wflag) { sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR; } else { #else { #endif if (!fflag || errno != ENOENT) { fprintf(stderr, "lstat: %s: %s: %s " CUR_LINE() "\n", argv0, f, strerror(errno)); eval = 1; } continue; } #ifdef FTS_WHITEOUT } else if (Wflag) { fprintf(stderr, "%s: %s: %s\n", argv0, f, strerror(EEXIST)); eval = 1; continue; #endif } if (S_ISDIR(sb.st_mode) && !dflag) { fprintf(stderr, "%s: %s: is a directory\n", argv0, f); eval = 1; continue; } if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb)) continue; rval = 0; #ifdef UF_APPEND if (!uid && (sb.st_flags & (UF_APPEND|UF_IMMUTABLE)) && !(sb.st_flags & (SF_APPEND|SF_IMMUTABLE))) rval = chflags(f, sb.st_flags & ~(UF_APPEND|UF_IMMUTABLE)); #endif if (rval == 0) { if (S_ISWHT(sb.st_mode)) { rval = undelete(f); operation = "undelete"; } else if (S_ISDIR(sb.st_mode)) { rval = rmdir(f); operation = "rmdir"; } else { if (Pflag) if (!rm_overwrite(f, &sb)) continue; rval = unlink(f); #ifdef _MSC_VER if (rval != 0) { chmod(f, 0777); rval = unlink(f); } #endif operation = "unlink"; } } if (rval && (!fflag || errno != ENOENT)) { fprintf(stderr, "%s: %s: %s: %s" CUR_LINE() "\n", operation, argv0, f, strerror(errno)); eval = 1; } if (vflag && rval == 0) (void)printf("%s\n", f); } return eval; }