static char ftypelet(unsigned mode) { if (S_ISREG(mode)) return '-'; if (S_ISDIR(mode)) return 'd'; #ifdef S_ISBLK if (S_ISBLK(mode)) return 'b'; #endif #ifdef S_ISCHR if (S_ISCHR(mode)) return 'c'; #endif #ifdef S_ISFIFO if (S_ISFIFO(mode)) return 'p'; #endif #ifdef S_ISLNK if (S_ISLNK(mode)) return 'l'; #endif #ifdef S_ISSOCK if (S_ISSOCK(mode)) return 's'; #endif #ifdef S_ISMPC if (S_ISMPC(mode)) return 'm'; #endif #ifdef S_ISNWK if (S_ISNWK(mode)) return 'n'; #endif #ifdef S_ISOFD if (S_ISOFD(mode)) return 'M'; /* Cray migrated dmf file. */ #endif #ifdef S_ISOFL if (S_ISOFL(mode)) return 'M'; /* Cray migrated dmf file. */ #endif return '?'; }
static char ftypelet (mode_t bits) { #ifdef S_ISBLK if (S_ISBLK (bits)) return 'b'; #endif if (S_ISCHR (bits)) return 'c'; if (S_ISDIR (bits)) return 'd'; if (S_ISREG (bits)) return '-'; #ifdef S_ISFIFO if (S_ISFIFO (bits)) return 'p'; #endif #ifdef S_ISLNK if (S_ISLNK (bits)) return 'l'; #endif #ifdef S_ISSOCK if (S_ISSOCK (bits)) return 's'; #endif #ifdef S_ISMPC if (S_ISMPC (bits)) return 'm'; #endif #ifdef S_ISNWK if (S_ISNWK (bits)) return 'n'; #endif return '?'; }
static char ftypelet (mode_t bits) { #ifdef S_ISBLK if (S_ISBLK (bits)) return 'b'; #endif if (S_ISCHR (bits)) return 'c'; if (S_ISDIR (bits)) return 'd'; if (S_ISREG (bits)) return '-'; #ifdef S_ISFIFO if (S_ISFIFO (bits)) return 'p'; #endif #ifdef S_ISLNK if (S_ISLNK (bits)) return 'l'; #endif #ifdef S_ISSOCK if (S_ISSOCK (bits)) return 's'; #endif #ifdef S_ISMPC if (S_ISMPC (bits)) return 'm'; #endif #ifdef S_ISNWK if (S_ISNWK (bits)) return 'n'; #endif #ifdef S_ISDOOR if (S_ISDOOR (bits)) return 'D'; #endif #ifdef S_ISCTG if (S_ISCTG (bits)) return 'C'; #endif /* 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. */ #ifdef S_ISOFD if (S_ISOFD (bits)) /* off line, with data */ return 'M'; #endif #ifdef S_ISOFL /* off line, with no data */ if (S_ISOFL (bits)) return 'M'; #endif return '?'; }
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 '?'; }
void stat_mode(unsigned char **p, int *l, struct stat *stp) { unsigned char c = '?'; if (stp) { if (0) ; #ifdef S_ISBLK else if (S_ISBLK(stp->st_mode)) c = 'b'; #endif #ifdef S_ISCHR else if (S_ISCHR(stp->st_mode)) c = 'c'; #endif else if (S_ISDIR(stp->st_mode)) c = 'd'; else if (S_ISREG(stp->st_mode)) c = '-'; #ifdef S_ISFIFO else if (S_ISFIFO(stp->st_mode)) c = 'p'; #endif #ifdef S_ISLNK else if (S_ISLNK(stp->st_mode)) c = 'l'; #endif #ifdef S_ISSOCK else if (S_ISSOCK(stp->st_mode)) c = 's'; #endif #ifdef S_ISNWK else if (S_ISNWK(stp->st_mode)) c = 'n'; #endif } add_chr_to_str(p, l, c); #ifdef FS_UNIX_RIGHTS { unsigned char rwx[10] = "---------"; if (stp) { int mode = stp->st_mode; setrwx(mode << 0, &rwx[0]); setrwx(mode << 3, &rwx[3]); setrwx(mode << 6, &rwx[6]); setst(mode, rwx); } add_to_str(p, l, rwx); } #endif add_chr_to_str(p, l, ' '); }
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 '?'; }
S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH, S_ISUID, S_ISGID, S_ISVTX, S_ISBLK (S_IFREG), 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));
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 void statmodeprint(mode_t mode, char *outbuf, int flags) { if (flags & STF_RAW) { sprintf(outbuf, (flags & STF_OCTAL) ? "0%lo" : "%lu", (unsigned long)mode); if (flags & STF_STRING) strcat(outbuf, " ("); } if (flags & STF_STRING) { static const char *modes = "?rwxrwxrwx"; #ifdef __CYGWIN__ static mode_t mflags[9] = { 0 }; #else static const mode_t mflags[9] = { S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH }; #endif const mode_t *mfp = mflags; char pm[11]; int i; #ifdef __CYGWIN__ if (mflags[0] == 0) { mflags[0] = S_IRUSR; mflags[1] = S_IWUSR; mflags[2] = S_IXUSR; mflags[3] = S_IRGRP; mflags[4] = S_IWGRP; mflags[5] = S_IXGRP; mflags[6] = S_IROTH; mflags[7] = S_IWOTH; mflags[8] = S_IXOTH; } #endif if (S_ISBLK(mode)) *pm = 'b'; else if (S_ISCHR(mode)) *pm = 'c'; else if (S_ISDIR(mode)) *pm = 'd'; else if (S_ISDOOR(mode)) *pm = 'D'; else if (S_ISFIFO(mode)) *pm = 'p'; else if (S_ISLNK(mode)) *pm = 'l'; else if (S_ISMPC(mode)) *pm = 'm'; else if (S_ISNWK(mode)) *pm = 'n'; else if (S_ISOFD(mode)) *pm = 'M'; else if (S_ISOFL(mode)) *pm = 'M'; else if (S_ISREG(mode)) *pm = '-'; else if (S_ISSOCK(mode)) *pm = 's'; else *pm = '?'; for (i = 1; i <= 9; i++) pm[i] = (mode & *mfp++) ? modes[i] : '-'; pm[10] = '\0'; if (mode & S_ISUID) pm[3] = (mode & S_IXUSR) ? 's' : 'S'; if (mode & S_ISGID) pm[6] = (mode & S_IXGRP) ? 's' : 'S'; if (mode & S_ISVTX) pm[9] = (mode & S_IXOTH) ? 't' : 'T'; pm[10] = 0; strcat(outbuf, pm); if (flags & STF_RAW) strcat(outbuf, ")"); } }
static void copy_out_one_file (int handle, dynamic_string *input_name, struct stat *stat_info) { struct new_cpio_header header; int input_handle; /* source file descriptor */ char *p; /* Set values in output header. */ header.c_magic = 070707; header.c_dev_maj = major (stat_info->st_dev); header.c_dev_min = minor (stat_info->st_dev); header.c_ino = stat_info->st_ino; #if DOSWIN /* DJGPP doesn't support st_rdev. Repair that. */ stat_info->st_rdev = stat_info->st_dev; #endif /* For POSIX systems that don't define the S_IF macros, we can't assume that S_ISfoo means the standard Unix S_IFfoo bit(s) are set. So do it manually, with a different name. Bleah. */ header.c_mode = (stat_info->st_mode & 07777); if (S_ISREG (stat_info->st_mode)) header.c_mode |= CP_IFREG; else if (S_ISDIR (stat_info->st_mode)) header.c_mode |= CP_IFDIR; #ifdef S_ISBLK else if (S_ISBLK (stat_info->st_mode)) header.c_mode |= CP_IFBLK; #endif #ifdef S_ISCHR else if (S_ISCHR (stat_info->st_mode)) header.c_mode |= CP_IFCHR; #endif #ifdef S_ISFIFO else if (S_ISFIFO (stat_info->st_mode)) header.c_mode |= CP_IFIFO; #endif #ifdef S_ISLNK else if (S_ISLNK (stat_info->st_mode)) header.c_mode |= CP_IFLNK; #endif #ifdef S_ISSOCK else if (S_ISSOCK (stat_info->st_mode)) header.c_mode |= CP_IFSOCK; #endif #ifdef S_ISNWK else if (S_ISNWK (stat_info->st_mode)) header.c_mode |= CP_IFNWK; #endif header.c_uid = stat_info->st_uid; header.c_gid = stat_info->st_gid; header.c_nlink = stat_info->st_nlink; header.c_rdev_maj = major (stat_info->st_rdev); header.c_rdev_min = minor (stat_info->st_rdev); header.c_mtime = (stat_info->st_mtime < 0) ? 0 :stat_info->st_mtime; header.c_filesize = stat_info->st_size; header.c_chksum = 0; header.c_tar_linkname = NULL; /* Handle HPUX CDF files. */ possibly_munge_cdf_directory_name (input_name->string, &header); if ((*name_too_long) (header.c_name)) { error (0, 0, _("%s: file name too long"), header.c_name); return; } /* FIXME: there is a memory leak here, between this and the HPUX stuff above. */ header.c_name = possibly_rename_file (header.c_name); /* Copy the named file to the output. */ switch (header.c_mode & CP_IFMT) { case CP_IFREG: #ifndef __MSDOS__ if (archive_format == V7_FORMAT || archive_format == POSIX_FORMAT || archive_format == GNUTAR_FORMAT) { char *otherfile; if ((otherfile = find_inode_file (header.c_ino, header.c_dev_maj, header.c_dev_min))) { header.c_tar_linkname = otherfile; (*header_writer) (&header, handle); break; } } if ((archive_format == NEW_ASCII_FORMAT || archive_format == CRC_ASCII_FORMAT) && header.c_nlink > 1) if (last_link (&header) ) writeout_other_defers (&header, handle); else { add_link_defer (&header); break; } #endif input_handle = open (input_name->string, O_RDONLY | O_BINARY, 0); if (input_handle < 0) { error (0, errno, "%s", input_name->string); return; } if (archive_format == CRC_ASCII_FORMAT) header.c_chksum = read_for_checksum (input_handle, header.c_filesize, input_name->string); (*header_writer) (&header, handle); copy_files_disk_to_tape (input_handle, handle, header.c_filesize, input_name->string); #ifndef __MSDOS__ if (archive_format == V7_FORMAT || archive_format == POSIX_FORMAT || archive_format == GNUTAR_FORMAT) add_inode (header.c_ino, header.c_name, header.c_dev_maj, header.c_dev_min); #endif tape_pad_output (handle, header.c_filesize); if (close (input_handle) < 0) error (0, errno, "%s", input_name->string); if (reset_access_time_option) { struct utimbuf times; /* Initialize this in case it has members we don't know to set. */ memset (×, 0, sizeof (struct utimbuf)); times.actime = stat_info->st_atime; times.modtime = stat_info->st_mtime; /* Silently ignore EROFS because reading the file won't have upset its timestamp if it's on a read-only filesystem. */ if (utime (header.c_name, ×) < 0 && errno != EROFS) error (0, errno, _("%s: error resetting file access time"), header.c_name); } break; case CP_IFDIR: header.c_filesize = 0; (*header_writer) (&header, handle); break; #ifndef __MSDOS__ case CP_IFCHR: case CP_IFBLK: #ifdef CP_IFSOCK case CP_IFSOCK: #endif #ifdef CP_IFIFO case CP_IFIFO: #endif if (archive_format == V7_FORMAT) { error (0, 0, _("%s not dumped: not a regular file"), header.c_name); return; } else if (archive_format == POSIX_FORMAT || archive_format == GNUTAR_FORMAT) { char *otherfile = find_inode_file (header.c_ino, header.c_dev_maj, header.c_dev_min); if (otherfile) { /* This file is linked to another file already in the archive, so write it out as a hard link. */ header.c_mode = (stat_info->st_mode & 07777); header.c_mode |= CP_IFREG; header.c_tar_linkname = otherfile; (*header_writer) (&header, handle); break; } add_inode (header.c_ino, header.c_name, header.c_dev_maj, header.c_dev_min); } header.c_filesize = 0; (*header_writer) (&header, handle); break; #endif #ifdef CP_IFLNK case CP_IFLNK: { char *link_name = (char *) xmalloc (stat_info->st_size + 1); int link_size = readlink (input_name->string, link_name, stat_info->st_size); if (link_size < 0) { error (0, errno, "%s", input_name->string); free (link_name); return; } header.c_filesize = link_size; if (archive_format == V7_FORMAT || archive_format == POSIX_FORMAT || archive_format == GNUTAR_FORMAT) { /* FIXME: tar can do long symlinks. */ if (link_size + 1 > 100) error (0, 0, _("%s: symbolic link too long"), header.c_name); else { link_name[link_size] = '\0'; header.c_tar_linkname = link_name; (*header_writer) (&header, handle); } } else { (*header_writer) (&header, handle); tape_buffered_write (link_name, handle, link_size); tape_pad_output (handle, link_size); } free (link_name); } break; #endif default: error (0, 0, _("%s: unknown file type"), input_name->string); } /* FIXME shouldn't do this for each file. Should maintain a dstring somewhere. */ free (header.c_name); header.c_name = NULL; }