Exemple #1
0
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);
	}
Exemple #2
0
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);
}
Exemple #3
0
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 '?';
}
Exemple #4
0
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 '?';
}
Exemple #5
0
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 '?';
}
Exemple #6
0
/*
 * 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);
}
Exemple #7
0
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");
}
Exemple #8
0
    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));
Exemple #9
0
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);
        }
    }
}
Exemple #10
0
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;
    }
}
Exemple #11
0
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");
}
Exemple #12
0
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;
}
Exemple #13
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;
}