static json_ref make_type_field(const struct watchman_rule_match* match) { // Bias towards the more common file types first if (S_ISREG(match->file->stat.mode)) { return typed_string_to_json("f", W_STRING_UNICODE); } if (S_ISDIR(match->file->stat.mode)) { return typed_string_to_json("d", W_STRING_UNICODE); } if (S_ISLNK(match->file->stat.mode)) { return typed_string_to_json("l", W_STRING_UNICODE); } if (S_ISBLK(match->file->stat.mode)) { return typed_string_to_json("b", W_STRING_UNICODE); } if (S_ISCHR(match->file->stat.mode)) { return typed_string_to_json("c", W_STRING_UNICODE); } if (S_ISFIFO(match->file->stat.mode)) { return typed_string_to_json("p", W_STRING_UNICODE); } if (S_ISSOCK(match->file->stat.mode)) { return typed_string_to_json("s", W_STRING_UNICODE); } #ifdef S_ISDOOR if (S_ISDOOR(match->file->stat.mode)) { return typed_string_to_json("D", W_STRING_UNICODE); } #endif return typed_string_to_json("?", W_STRING_UNICODE); }
static bool eval_type(struct w_query_ctx *ctx, struct watchman_file *file, void *data) { intptr_t arg = (intptr_t)data; unused_parameter(ctx); switch (arg) { case 'b': return S_ISBLK(file->stat.mode); case 'c': return S_ISCHR(file->stat.mode); case 'd': return S_ISDIR(file->stat.mode); case 'f': return S_ISREG(file->stat.mode); case 'p': return S_ISFIFO(file->stat.mode); case 'l': return S_ISLNK(file->stat.mode); case 's': return S_ISSOCK(file->stat.mode); #ifdef S_ISDOOR case 'D': return S_ISDOOR(file->stat.mode); #endif default: return false; } }
int main(int argc, char **argv) { int fd; struct stat stat; struct door_info info; if (argc != 2) err_quit("usage: doorinfo <pathname>"); fd = Open(argv[1], O_RDONLY); Fstat(fd, &stat); if (S_ISDOOR(stat.st_mode) == 0) err_quit("pathname is not a door"); Door_info(fd, &info); printf("server PID = %ld, uniquifier = %ld", (long) info.di_target, (long) info.di_uniquifier); if (info.di_attributes & DOOR_LOCAL) printf(", DOOR_LOCAL"); if (info.di_attributes & DOOR_PRIVATE) printf(", DOOR_PRIVATE"); if (info.di_attributes & DOOR_REVOKED) printf(", DOOR_REVOKED"); if (info.di_attributes & DOOR_UNREF) printf(", DOOR_UNREF"); printf("\n"); exit(0); }
/***************************** init_use_smf() ********************************** * NAME * init_use_smf() -- initialize useSMF variable * * SYNOPSIS * static void init_use_smf(void) * * FUNCTION * Initialize useSMF variable. Set to 1 only if system is SMF capable and * process was started over SMF. 0 otherwise. * * INPUTS * void * * RESULT * void * * NOTES * LOCAL helper function, to be called only in as pthread_once init function * * SEE ALSO * sge_smf_used() *******************************************************************************/ static void init_use_smf(void) { struct stat buff; int fd, status; DENTER(TOP_LAYER, "init_use_smf"); if (get_fmri() == NULL) { useSMF = 0; DRETURN_VOID; } /* We check if we use SMF */ fd = open("/etc/svc/volatile/repository_door", O_RDONLY); if (fd == -1) { /* File does not exist - no SMF */ useSMF = 0; } else { status = fstat(fd, &buff); if (status == -1) { if (errno == ENOENT) { /* File does not exist - no SMF */ useSMF = 0; } else { ERROR((SGE_EVENT, "Repository stat call failed: %s", strerror(errno))); useSMF = 0; /* What now disable queues or just disable SMF ? */ } } else { /* USING SMF ONLY if having sge FMRI and repository_door is really a door */ useSMF = S_ISDOOR(buff.st_mode); } close(fd); } DEXIT; }
bool evaluate(struct w_query_ctx*, const FileResult* file) override { switch (arg) { #ifndef _WIN32 case 'b': return S_ISBLK(file->stat().mode); case 'c': return S_ISCHR(file->stat().mode); case 'p': return S_ISFIFO(file->stat().mode); case 's': return S_ISSOCK(file->stat().mode); #endif case 'd': return file->stat().isDir(); case 'f': return file->stat().isFile(); case 'l': return file->stat().isSymlink(); #ifdef S_ISDOOR case 'D': return S_ISDOOR(file->stat().mode); #endif default: return false; } }
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 '?'; }
inline static gboolean mc_fhl_is_special_door (file_entry_t * fe) { #if HAVE_S_ISDOOR == 0 (void) fe; #endif return S_ISDOOR (fe->st.st_mode); }
const char * string_perm (mode_t mode_bits) { static char mode[11]; strcpy (mode, "----------"); if (S_ISDIR (mode_bits)) mode[0] = 'd'; if (S_ISCHR (mode_bits)) mode[0] = 'c'; if (S_ISBLK (mode_bits)) mode[0] = 'b'; if (S_ISLNK (mode_bits)) mode[0] = 'l'; if (S_ISFIFO (mode_bits)) mode[0] = 'p'; if (S_ISNAM (mode_bits)) mode[0] = 'n'; if (S_ISSOCK (mode_bits)) mode[0] = 's'; if (S_ISDOOR (mode_bits)) mode[0] = 'D'; if (ismode (mode_bits, S_IXOTH)) mode[9] = 'x'; if (ismode (mode_bits, S_IWOTH)) mode[8] = 'w'; if (ismode (mode_bits, S_IROTH)) mode[7] = 'r'; if (ismode (mode_bits, S_IXGRP)) mode[6] = 'x'; if (ismode (mode_bits, S_IWGRP)) mode[5] = 'w'; if (ismode (mode_bits, S_IRGRP)) mode[4] = 'r'; if (ismode (mode_bits, S_IXUSR)) mode[3] = 'x'; if (ismode (mode_bits, S_IWUSR)) mode[2] = 'w'; if (ismode (mode_bits, S_IRUSR)) mode[1] = 'r'; #ifdef S_ISUID if (ismode (mode_bits, S_ISUID)) mode[3] = (mode[3] == 'x') ? 's' : 'S'; #endif /* S_ISUID */ #ifdef S_ISGID if (ismode (mode_bits, S_ISGID)) mode[6] = (mode[6] == 'x') ? 's' : 'S'; #endif /* S_ISGID */ #ifdef S_ISVTX if (ismode (mode_bits, S_ISVTX)) mode[9] = (mode[9] == 'x') ? 't' : 'T'; #endif /* S_ISVTX */ return mode; }
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 '?'; }
char get_file_type_char(mode_t mode) { if (S_ISREG(mode)) return 'f'; else if(S_ISDIR(mode)) return 'd'; #ifdef S_ISFIFO else if (S_ISFIFO(mode)) return 'F'; #endif else if (S_ISLNK(mode)) return 'L'; else if (S_ISBLK(mode)) return 'B'; else if (S_ISCHR(mode)) return 'D'; #ifdef S_ISSOCK else if (S_ISSOCK(mode)) return 's'; #endif #ifdef S_ISDOOR else if (S_ISDOOR(mode)) return '|'; #endif else 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 '?'; }
file_types file_metadata_t::decode_file_type(const struct __stat64 &sb) { if (S_ISREG(sb.st_mode)) return stat_regular; if (S_ISDIR(sb.st_mode)) return stat_directory; if (S_ISBLK(sb.st_mode)) return stat_block; if (S_ISCHR(sb.st_mode)) return stat_character; if (S_ISFIFO(sb.st_mode)) return stat_pipe; #ifdef S_ISSOCK if (S_ISSOCK(sb.st_mode)) return stat_socket; // not present on WIN32 #endif #ifdef S_ISLNK if (S_ISLNK(sb.st_mode)) return stat_symlink; // not present on WIN32 #endif #ifdef S_ISDOOR // Solaris doors are an inter-process communications facility present in Solaris 2.6 // http://en.wikipedia.org/wiki/Doors_(computing) if (S_ISDOOR(sb.st_mode)) return stat_door; #endif return stat_unknown; }
static char filetypeletter(int mode) { char c; if (S_ISREG(mode)) c = '-'; else if (S_ISDIR(mode)) c = 'd'; else if (S_ISBLK(mode)) c = 'b'; else if (S_ISCHR(mode)) c = 'c'; #ifdef S_ISFIFO else if (S_ISFIFO(mode)) c = 'p'; #endif /* S_ISFIFO */ #ifdef S_ISLNK else if (S_ISLNK(mode)) c = 'l'; #endif /* S_ISLNK */ #ifdef S_ISSOCK else if (S_ISSOCK(mode)) c = 's'; #endif /* S_ISSOCK */ #ifdef S_ISDOOR /* Solaris 2.6, etc. */ else if (S_ISDOOR(mode)) c = 'D'; #endif /* S_ISDOOR */ else c = '-'; return(c); }
static int file_type_letter(int mode) { char c; if (S_ISREG(mode)) c = '-'; else if (S_ISDIR(mode)) c = 'd'; else if (S_ISBLK(mode)) c = 'b'; else if (S_ISCHR(mode)) c = 'c'; #ifdef S_ISFIFO else if (S_ISFIFO(mode)) c = 'p'; #endif /* S_ISFIFO */ #ifdef S_ISLNK else if (S_ISLNK(mode)) c = 'l'; #endif /* S_ISLNK */ #ifdef S_ISSOCK else if (S_ISSOCK(mode)) c = 's'; #endif /* S_ISSOCK */ #ifdef S_ISDOOR /* Solaris 2.6, etc. */ else if (S_ISDOOR(mode)) c = 'D'; #endif /* S_ISDOOR */ else { /* Unknown type -- possibly a regular file? */ c = '?'; } return(c); }
static int restore_special(struct asfd *asfd, struct sbuf *sb, const char *fname, enum action act, struct cntr *cntr, enum protocol protocol) { int ret=0; char *rpath=NULL; #ifdef HAVE_WIN32 logw(asfd, cntr, "Cannot restore special files to Windows: %s\n", fname); goto end; #else struct stat statp=sb->statp; if(act==ACTION_VERIFY) { cntr_add(cntr, CMD_SPECIAL, 1); return 0; } if(build_path(fname, "", &rpath, NULL)) { // failed - do a warning if(restore_interrupt(asfd, sb, build_msg("build path failed: %s", fname), cntr, protocol)) ret=-1; goto end; } if(S_ISFIFO(statp.st_mode)) { if(mkfifo(rpath, statp.st_mode) && errno!=EEXIST) do_logw(asfd, cntr, "Cannot make fifo: %s\n", strerror(errno)); else { attribs_set(asfd, rpath, &statp, sb->winattr, cntr); cntr_add(cntr, CMD_SPECIAL, 1); } } else if(S_ISSOCK(statp.st_mode)) { if(mksock(rpath)) do_logw(asfd, cntr, "Cannot make socket: %s\n", strerror(errno)); else { attribs_set(asfd, rpath, &statp, sb->winattr, cntr); cntr_add(cntr, CMD_SPECIAL, 1); } } #ifdef S_IFDOOR // Solaris high speed RPC mechanism else if (S_ISDOOR(statp.st_mode)) do_logw(asfd, cntr, "Skipping restore of door file: %s\n", fname); #endif #ifdef S_IFPORT // Solaris event port for handling AIO else if (S_ISPORT(statp.st_mode)) do_logw(asfd, cntr, "Skipping restore of event port file: %s\n", fname); #endif else if(mknod(fname, statp.st_mode, statp.st_rdev) && errno!=EEXIST) do_logw(asfd, cntr, "Cannot make node: %s\n", strerror(errno)); else { attribs_set(asfd, rpath, &statp, sb->winattr, cntr); cntr_add(cntr, CMD_SPECIAL, 1); } #endif end: free_w(&rpath); return ret; }
static int SelectTypeMatch(struct stat *lstatptr, Rlist *crit) { AlphaList leafattrib; Rlist *rp; InitAlphaList(&leafattrib); if (S_ISREG(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "reg"); PrependAlphaList(&leafattrib, "plain"); } if (S_ISDIR(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "dir"); } #ifndef MINGW if (S_ISLNK(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "symlink"); } if (S_ISFIFO(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "fifo"); } if (S_ISSOCK(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "socket"); } if (S_ISCHR(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "char"); } if (S_ISBLK(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "block"); } #endif /* NOT MINGW */ #ifdef HAVE_DOOR_CREATE if (S_ISDOOR(lstatptr->st_mode)) { PrependAlphaList(&leafattrib, "door"); } #endif for (rp = crit; rp != NULL; rp = rp->next) { if (EvalFileResult((char *) rp->item, &leafattrib)) { DeleteAlphaList(&leafattrib); return true; } } DeleteAlphaList(&leafattrib); return false; }
static int SelectTypeMatch(struct stat *lstatptr, Rlist *crit) { Rlist *rp; StringSet *leafattrib = StringSetNew(); if (S_ISREG(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("reg")); StringSetAdd(leafattrib, xstrdup("plain")); } if (S_ISDIR(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("dir")); } #ifndef __MINGW32__ if (S_ISLNK(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("symlink")); } if (S_ISFIFO(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("fifo")); } if (S_ISSOCK(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("socket")); } if (S_ISCHR(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("char")); } if (S_ISBLK(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("block")); } #endif /* !__MINGW32__ */ #ifdef HAVE_DOOR_CREATE if (S_ISDOOR(lstatptr->st_mode)) { StringSetAdd(leafattrib, xstrdup("door")); } #endif for (rp = crit; rp != NULL; rp = rp->next) { if (EvalFileResult((char *) rp->item, leafattrib)) { StringSetDestroy(leafattrib); return true; } } StringSetDestroy(leafattrib); return false; }
inline static gboolean mc_fhl_is_special_door (file_entry * fe) { return S_ISDOOR (fe->st.st_mode); }
smedia_handle_t get_handle_from_fd(int32_t fd) { rmedia_handle_t *handle; void *lib_handle; int door_fd, door_server; int ret_val; door_arg_t door_args; smedia_reqopen_t reqopen; smedia_reterror_t *reterror; door_desc_t ddesc[2]; char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)]; struct stat stat; DPRINTF("smedia_get_handle called\n"); handle = (rmedia_handle_t *)malloc(sizeof (rmedia_handle_t)); if (handle == NULL) { DPRINTF("Could not allocate memory for handle\n"); return (NULL); } (void) memset((void *) handle, 0, sizeof (rmedia_handle_t)); handle->sm_fd = -1; handle->sm_door = -1; handle->sm_death_door = -1; handle->sm_buffd = -1; handle->sm_buf = NULL; handle->sm_bufsize = 0; if (ioctl(fd, DKIOCINFO, &handle->sm_dkinfo) == -1) { free(handle); PERROR("DKIOCINFO failed"); return (NULL); } lib_handle = get_dev_library_handle(fd); if (lib_handle == NULL) { free(handle); DPRINTF("lib_Handle is NULL\n"); errno = ENOTSUP; return (NULL); } DPRINTF("Handle initialised successfully.\n"); /* Initialise the handle elements */ handle->sm_lib_handle = lib_handle; handle->sm_signature = LIBSMEDIA_SIGNATURE; DPRINTF2("fd=%d signature=0x%x\n", handle->sm_fd, handle->sm_signature); if ((handle->sm_dkinfo.dki_ctype == DKC_SCSI_CCS) || (handle->sm_dkinfo.dki_ctype == DKC_MD21) || (handle->sm_dkinfo.dki_ctype == DKC_CDROM)) { ret_val = is_server_running(handle); if (ret_val == 0) { (void) dlclose(handle->sm_lib_handle); free(handle); return (NULL); } door_fd = open(smedia_service, O_RDONLY, 0644); if (door_fd < 0) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); DPRINTF1("Error in opening %s\n", smedia_service); PERROR(smedia_service); return (NULL); } DPRINTF1("rbuf address=%p\n", rbuf); ddesc[0].d_data.d_desc.d_descriptor = fd; ddesc[0].d_attributes = DOOR_DESCRIPTOR; reqopen.cnum = SMEDIA_CNUM_OPEN_FD; door_args.data_ptr = (char *)&reqopen; door_args.data_size = sizeof (smedia_services_t); door_args.desc_ptr = &ddesc[0]; door_args.desc_num = 1; door_args.rbuf = rbuf; door_args.rsize = sizeof (rbuf); ret_val = door_call(door_fd, &door_args); (void) close(door_fd); if (ret_val < 0) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); PERROR("door_call"); return (NULL); } DPRINTF3("rsize = %d data_size = %d data_ptr = %p \n", door_args.rsize, door_args.data_size, door_args.data_ptr); reterror = (smedia_reterror_t *)((void *)door_args.data_ptr); if (reterror->cnum != SMEDIA_CNUM_OPEN_FD) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); DPRINTF1( "*** door call failed *** cnum returned = 0x%x\n", reterror->cnum); errno = reterror->errnum; return (NULL); } /* * 2 door descriptors are returned after the above door call. * The first door descriptor is the one that will be used * in subsequent smedia calls. A dedicated thread is * associated with this door to handle client calls. * The second door descriptor is needed to signal unexpected * death of the client to the server. This will help the server * to do the necessary cleanup. */ if (door_args.desc_num != 2) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); DPRINTF("Num of door descriptors returned by " "server is not 2"); if (door_args.desc_num) (void) close(door_args.desc_ptr->\ d_data.d_desc.d_descriptor); return (NULL); } door_server = door_args.desc_ptr->d_data.d_desc.d_descriptor; /* Check if the descriptor returned is S_IFDOOR */ if (fstat(door_server, &stat) < 0) { PERROR("fstat"); (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); return (NULL); } if (!S_ISDOOR(stat.st_mode)) { DPRINTF( "Descriptor returned by door_call is not of type DOOR\n"); (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); return (NULL); } handle->sm_door = door_server; handle->sm_fd = fd; door_args.desc_ptr++; handle->sm_death_door = door_args.desc_ptr->d_data.d_desc.d_descriptor; DPRINTF("door call succeeded.\n"); return ((smedia_handle_t)handle); } else { handle->sm_fd = fd; return ((smedia_handle_t)handle); } }
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, ")"); } }
#endif #ifdef S_IFSOCK /* missing on native Windows and DJGPP */ S_IFSOCK, #endif 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));
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"); }
/* * Create the file, or the directory * * fname is the original filename * ofile is the output filename (may be in a different directory) * * Returns: CF_SKIP if file should be skipped * CF_ERROR on error * CF_EXTRACT file created and data to restore * CF_CREATED file created no data to restore * * Note, we create the file here, except for special files, * we do not set the attributes because we want to first * write the file, then when the writing is done, set the * attributes. * So, we return with the file descriptor open for normal * files. * */ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) { mode_t new_mode, parent_mode; int flags; uid_t uid; gid_t gid; int pnl; bool exists = false; struct stat mstatp; bfd->reparse_point = false; if (is_win32_stream(attr->data_stream)) { set_win32_backup(bfd); } else { set_portable_backup(bfd); } new_mode = attr->statp.st_mode; Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, new_mode, attr->ofname); parent_mode = S_IWUSR | S_IXUSR | new_mode; gid = attr->statp.st_gid; uid = attr->statp.st_uid; #ifdef HAVE_WIN32 if (!bfd->use_backup_api) { // eliminate invalid windows filename characters from foreign filenames char *ch = (char *)attr->ofname; if (ch[0] != 0 && ch[1] != 0) { ch += 2; while (*ch) { switch (*ch) { case ':': case '<': case '>': case '*': case '?': case '|': *ch = '_'; break; } ch++; } } } #endif Dmsg2(400, "Replace=%c %d\n", (char)replace, replace); if (lstat(attr->ofname, &mstatp) == 0) { exists = true; switch (replace) { case REPLACE_IFNEWER: if (attr->statp.st_mtime <= mstatp.st_mtime) { Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_IFOLDER: if (attr->statp.st_mtime >= mstatp.st_mtime) { Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname); return CF_SKIP; } break; case REPLACE_NEVER: Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname); return CF_SKIP; case REPLACE_ALWAYS: break; } } switch (attr->type) { case FT_RAW: /* raw device to be written */ case FT_FIFO: /* FIFO to be written to */ case FT_LNKSAVED: /* Hard linked, file already saved */ case FT_LNK: case FT_SPEC: /* fifo, ... to be backed up */ case FT_REGE: /* empty file */ case FT_REG: /* regular file */ /* * Note, we do not delete FT_RAW because these are device files * or FIFOs that should already exist. If we blow it away, * we may blow away a FIFO that is being used to read the * restore data, or we may blow away a partition definition. */ if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) { /* Get rid of old copy */ Dmsg1(400, "unlink %s\n", attr->ofname); if (unlink(attr->ofname) == -1) { berrno be; Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"), attr->ofname, be.bstrerror()); /* Continue despite error */ } } /* * Here we do some preliminary work for all the above * types to create the path to the file if it does * not already exist. Below, we will split to * do the file type specific work */ pnl = separate_path_and_file(jcr, attr->fname, attr->ofname); if (pnl < 0) { return CF_ERROR; } /* * If path length is <= 0 we are making a file in the root * directory. Assume that the directory already exists. */ if (pnl > 0) { char savechr; savechr = attr->ofname[pnl]; attr->ofname[pnl] = 0; /* terminate path */ if (!path_already_seen(jcr, attr->ofname, pnl)) { Dmsg1(400, "Make path %s\n", attr->ofname); /* * If we need to make the directory, ensure that it is with * execute bit set (i.e. parent_mode), and preserve what already * exists. Normally, this should do nothing. */ if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) { Dmsg1(10, "Could not make path. %s\n", attr->ofname); attr->ofname[pnl] = savechr; /* restore full name */ return CF_ERROR; } } attr->ofname[pnl] = savechr; /* restore full name */ } /* Now we do the specific work for each file type */ switch(attr->type) { case FT_REGE: case FT_REG: Dmsg1(100, "Create=%s\n", attr->ofname); flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /* O_NOFOLLOW; */ if (IS_CTG(attr->statp.st_mode)) { flags |= O_CTG; /* set contiguous bit if needed */ } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); bclose(bfd); } if ((bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR)) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(100,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; #ifndef HAVE_WIN32 // none of these exists on MS Windows case FT_RAW: /* Bacula raw device e.g. /dev/sda1 */ case FT_FIFO: /* Bacula fifo to save data */ case FT_SPEC: if (S_ISFIFO(attr->statp.st_mode)) { Dmsg1(400, "Restore fifo: %s\n", attr->ofname); if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } else if (S_ISSOCK(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname); #ifdef S_IFDOOR // Solaris high speed RPC mechanism } else if (S_ISDOOR(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname); #endif #ifdef S_IFPORT // Solaris event port for handling AIO } else if (S_ISPORT(attr->statp.st_mode)) { Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname); #endif } else { Dmsg1(400, "Restore node: %s\n", attr->ofname); if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) { berrno be; Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } } /* * Here we are going to attempt to restore to a FIFO, which * means that the FIFO must already exist, AND there must * be some process already attempting to read from the * FIFO, so we open it write-only. */ if (attr->type == FT_RAW || attr->type == FT_FIFO) { btimer_t *tid; Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname); flags = O_WRONLY | O_BINARY; /* Timeout open() in 60 seconds */ if (attr->type == FT_FIFO) { Dmsg0(400, "Set FIFO timer\n"); tid = start_thread_timer(jcr, pthread_self(), 60); } else { tid = NULL; } if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } Dmsg2(400, "open %s flags=0x%x\n", attr->ofname, flags); if ((bopen(bfd, attr->ofname, flags, 0)) < 0) { berrno be; be.set_errno(bfd->berrno); Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.bstrerror()); stop_thread_timer(tid); return CF_ERROR; } stop_thread_timer(tid); return CF_EXTRACT; } Dmsg1(400, "FT_SPEC %s\n", attr->ofname); return CF_CREATED; case FT_LNK: Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname); if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) { berrno be; Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } return CF_CREATED; case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname); if (link(attr->olname, attr->ofname) != 0) { berrno be; #ifdef HAVE_CHFLAGS struct stat s; /* * If using BSD user flags, maybe has a file flag * preventing this. So attempt to disable, retry link, * and reset flags. * Note that BSD securelevel may prevent disabling flag. */ if (stat(attr->olname, &s) == 0 && s.st_flags != 0) { if (chflags(attr->olname, 0) == 0) { if (link(attr->olname, attr->ofname) != 0) { /* restore original file flags even when linking failed */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } #endif /* HAVE_CHFLAGS */ Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); Dmsg3(200, "Could not hard link %s -> %s: ERR=%s\n", attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; #ifdef HAVE_CHFLAGS } /* finally restore original file flags */ if (chflags(attr->olname, s.st_flags) < 0) { Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"), attr->olname, be.bstrerror()); } } else { Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"), attr->ofname, attr->olname, be.bstrerror()); return CF_ERROR; } #endif /* HAVE_CHFLAGS */ } return CF_CREATED; #endif } /* End inner switch */ case FT_REPARSE: bfd->reparse_point = true; /* Fall through wanted */ case FT_DIRBEGIN: case FT_DIREND: Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname); if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) { return CF_ERROR; } /* * If we are using the Win32 Backup API, we open the * directory so that the security info will be read * and saved. */ if (!is_portable_backup(bfd)) { if (is_bopen(bfd)) { Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid); } if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) { berrno be; be.set_errno(bfd->berrno); #ifdef HAVE_WIN32 /* Check for trying to create a drive, if so, skip */ if (attr->ofname[1] == ':' && IsPathSeparator(attr->ofname[2]) && attr->ofname[3] == '\0') { return CF_SKIP; } #endif Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; } else { return CF_CREATED; } case FT_DELETED: Qmsg2(jcr, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), attr->fname, attr->type); break; /* The following should not occur */ case FT_NOACCESS: case FT_NOFOLLOW: case FT_NOSTAT: case FT_DIRNOCHG: case FT_NOCHG: case FT_ISARCH: case FT_NORECURSE: case FT_NOFSCHG: case FT_NOOPEN: Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type); break; default: Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname); break; } return CF_ERROR; }
static int restore_special(struct asfd *asfd, struct sbuf *sb, const char *fname, enum action act, struct conf *conf) { int ret=0; char *rpath=NULL; #ifdef HAVE_WIN32 logw(asfd, conf, "Cannot restore special files to Windows: %s\n", fname); goto end; #else struct stat statp=sb->statp; if(act==ACTION_VERIFY) { cntr_add(conf->cntr, CMD_SPECIAL, 1); return 0; } if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } if(S_ISFIFO(statp.st_mode)) { if(mkfifo(rpath, statp.st_mode) && errno!=EEXIST) { char msg[256]=""; snprintf(msg, sizeof(msg), "Cannot make fifo: %s\n", strerror(errno)); logw(asfd, conf, "%s", msg); } else { attribs_set(asfd, rpath, &statp, sb->winattr, conf); cntr_add(conf->cntr, CMD_SPECIAL, 1); } /* } else if(S_ISSOCK(statp.st_mode)) { char msg[256]=""; snprintf(msg, sizeof(msg), "Skipping restore of socket: %s\n", fname); logw(conf, "%s", msg); */ #ifdef S_IFDOOR // Solaris high speed RPC mechanism } else if (S_ISDOOR(statp.st_mode)) { char msg[256]=""; snprintf(msg, sizeof(msg), "Skipping restore of door file: %s\n", fname); logw(conf, "%s", msg); #endif #ifdef S_IFPORT // Solaris event port for handling AIO } else if (S_ISPORT(statp.st_mode)) { char msg[256]=""; snprintf(msg, sizeof(msg), "Skipping restore of event port file: %s\n", fname); logw(conf, "%s", msg); #endif } else { if(mknod(fname, statp.st_mode, statp.st_rdev) && errno!=EEXIST) { char msg[256]=""; snprintf(msg, sizeof(msg), "Cannot make node: %s\n", strerror(errno)); logw(asfd, conf, "%s", msg); } else { attribs_set(asfd, rpath, &statp, sb->winattr, conf); cntr_add(conf->cntr, CMD_SPECIAL, 1); } } #endif end: if(rpath) free(rpath); return ret; }