For portability, don't rely on libc's strmode(3). <sigh>

This commit is contained in:
Tim Kientzle 2004-05-03 21:05:59 +00:00
parent 37c9eaae29
commit 9644b0783f
3 changed files with 53 additions and 1 deletions

View File

@ -85,6 +85,7 @@ struct bsdtar {
const char *bsdtar_progname(void);
void bsdtar_errc(int _eval, int _code, const char *fmt, ...);
void bsdtar_strmode(struct archive_entry *entry, char *bp);
void bsdtar_warnc(int _code, const char *fmt, ...);
void cleanup_exclusions(struct bsdtar *);
void exclude(struct bsdtar *, const char *pattern);

View File

@ -224,7 +224,7 @@ list_item_verbose(struct bsdtar *bsdtar, struct archive_entry *entry)
}
if (!now)
time(&now);
strmode(st->st_mode, tmp);
bsdtar_strmode(entry, tmp);
fprintf(out, "%s %d ", tmp, st->st_nlink);
/* Use uname if it's present, else uid. */

View File

@ -27,6 +27,8 @@
#include "bsdtar_platform.h"
__FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <archive_entry.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
@ -171,3 +173,52 @@ yes(const char *fmt, ...)
return (0);
}
void
bsdtar_strmode(struct archive_entry *entry, char *bp)
{
static const char *perms = "?rwxrwxrwx ";
static const mode_t permbits[] =
{ S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP,
S_IROTH, S_IWOTH, S_IXOTH };
mode_t mode;
int i;
/* Fill in a default string, then selectively override. */
strcpy(bp, perms);
mode = archive_entry_mode(entry);
switch (mode & S_IFMT) {
case S_IFREG: bp[0] = '-'; break;
case S_IFBLK: bp[0] = 'b'; break;
case S_IFCHR: bp[0] = 'c'; break;
case S_IFDIR: bp[0] = 'd'; break;
case S_IFLNK: bp[0] = 'l'; break;
case S_IFSOCK: bp[0] = 's'; break;
#ifdef S_IFIFO
case S_IFIFO: bp[0] = 'p'; break;
#endif
#ifdef S_IFWHT
case S_IFWHT: bp[0] = 'w'; break;
#endif
}
for (i = 0; i < 9; i++)
if (!(mode & permbits[i]))
bp[i+1] = '-';
if (mode & S_ISUID) {
if (mode & S_IXUSR) bp[3] = 's';
else bp[3] = 'S';
}
if (mode & S_ISGID) {
if (mode & S_IXGRP) bp[6] = 's';
else bp[6] = 'S';
}
if (mode & S_ISVTX) {
if (mode & S_IXGRP) bp[9] = 't';
else bp[9] = 'T';
}
if (archive_entry_acl_count(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS))
bp[10] = '+';
}