示例#1
0
/* perform actions that are common to all NAMED group addresses: checking if 
   the entry exists, parsing options, ev.removing old filesystem entry or
   setting early owners and permissions.
   It applies options of PH_EARLY and PH_PREOPEN.
   If the path exists, its st_mode field is returned.
   After this sub you may proceed with open() or whatever...
   */
int _xioopen_named_early(int argc, const char *argv[], xiofile_t *xfd,
			 int groups,
		      bool *exists, struct opt *opts) {
   const char *path = argv[1];
   unsigned int iogroups = 0;
#if HAVE_STAT64
   struct stat64 statbuf;
#else
   struct stat statbuf;
#endif /* !HAVE_STAT64 */
   bool opt_unlink_early = false;

   if (argc != 2) {
      Error2("%s: wrong number of parameters (%d instead of 1)", argv[0]?argv[0]:"<named>", argc);
   }
   statbuf.st_mode = 0;
   /* find the appropriate groupbits */
   if (
#if HAVE_STAT64
       Stat64(path, &statbuf) < 0
#else
       Stat(path, &statbuf) < 0
#endif /* !HAVE_STAT64 */
      ) {
      if (errno != ENOENT) {
	 Error2("stat(\"%s\"): %s", path, strerror(errno));
	    return STAT_RETRYLATER;
      }
      iogroups = GROUP_REG;
      *exists = false;
   } else {
      iogroups = _groupbits(statbuf.st_mode);
      *exists = true;
   }

   if (applyopts_single(&xfd->stream, opts, PH_INIT) < 0)  return -1;
   applyopts(-1, opts, PH_INIT);

   retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
   if (*exists && opt_unlink_early) {
      Info1("\"%s\" already exists; removing it", path);
      if (Unlink(path) < 0) {
	 Error2("unlink(\"%s\"): %s", path, strerror(errno));
	 *exists = true;
      } else {
	 *exists = false;
      }
   }

   applyopts(-1, opts, PH_EARLY);
   applyopts_named(path, opts, PH_EARLY);
   if (*exists) {
      applyopts_named(path, opts, PH_PREOPEN);
   } else {
      dropopts(opts, PH_PREOPEN);
   }

   return statbuf.st_mode;
}
示例#2
0
/* analyse a file system entry, referred by file name */
int filan_file(const char *filename, FILE *outfile) {
   int fd = -1;
   int result;
#if HAVE_STAT64
   struct stat64 buf = {0};
#else
   struct stat buf = {0};
#endif /* !HAVE_STAT64 */

   if (filan_followsymlinks) {
#if HAVE_STAT64
      result = Stat64(filename, &buf);
#else
      result = Stat(filename, &buf);
#endif /* !HAVE_STAT64 */
      if (result < 0) {
	 Warn3("stat(\"%s\", %p): %s", filename, &buf, strerror(errno));
      }
   } else {
#if HAVE_STAT64
      result = Lstat64(filename, &buf);
#else
      result = Lstat(filename, &buf);
#endif /* !HAVE_STAT64 */
      if (result < 0) {
	 Warn3("lstat(\"%s\", %p): %s", filename, &buf, strerror(errno));
      }
   }
   switch (buf.st_mode&S_IFMT) {
#ifdef S_IFSOCK
   case S_IFSOCK: /* probably, it's useless to make a socket and describe it */
      break;
#endif /* S_IFSOCK */
   default:
      if ((fd =
	   Open(filename,  O_RDONLY|O_NOCTTY|O_NONBLOCK
#ifdef O_LARGEFILE
		|O_LARGEFILE
#endif
		, 0700))
	  < 0) {
	 Warn2("open(\"%s\", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0700): %s",
	       filename, strerror(errno));
      }
   }
     
   result = filan_stat(&buf, fd, -1, outfile);
   fputc('\n', outfile);
   return result;
}
示例#3
0
/* open a named or unnamed pipe/fifo */
static int xioopen_fifo(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3) {
   const char *pipename = argv[1];
   int rw = (xioflags & XIO_ACCMODE);
#if HAVE_STAT64
   struct stat64 pipstat;
#else
   struct stat pipstat;
#endif /* !HAVE_STAT64 */
   bool opt_unlink_early = false;
   bool opt_unlink_close = true;
   mode_t mode = 0666;
   int result;

   if (argc == 1) {
      return xioopen_fifo_unnamed(fd, fd->stream.opts);
   }

   if (argc != 2) {
      Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
   }

   if (applyopts_single(&fd->stream, opts, PH_INIT) < 0)  return -1;
   applyopts(-1, opts, PH_INIT);

   retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
   applyopts_named(pipename, opts, PH_EARLY);	/* umask! */
   applyopts(-1, opts, PH_EARLY);

   if (opt_unlink_early) {
      if (Unlink(pipename) < 0) {
	 if (errno == ENOENT) {
	    Warn2("unlink(%s): %s", pipename, strerror(errno));
	 } else {
	    Error2("unlink(%s): %s", pipename, strerror(errno));
	    return STAT_RETRYLATER;
	 }
      }
   }

   retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
   retropt_modet(opts, OPT_PERM, &mode);
   if (applyopts_named(pipename, opts, PH_EARLY) < 0) {
      return STAT_RETRYLATER;
   }
   if (applyopts_named(pipename, opts, PH_PREOPEN) < 0) {
      return STAT_RETRYLATER;
   }
   if (
#if HAVE_STAT64
       Stat64(pipename, &pipstat) < 0
#else
       Stat(pipename, &pipstat) < 0
#endif /* !HAVE_STAT64 */
      ) {
      if (errno != ENOENT) {
	 Error3("stat(\"%s\", %p): %s", pipename, &pipstat, strerror(errno));
      } else {
	 Debug1("xioopen_fifo(\"%s\"): does not exist, creating fifo", pipename);
#if 0
	 result = Mknod(pipename, S_IFIFO|mode, 0);
	 if (result < 0) {
	    Error3("mknod(%s, %d, 0): %s", pipename, mode, strerror(errno));
	    return STAT_RETRYLATER;
	 }
#else
	 result = Mkfifo(pipename, mode);
	 if (result < 0) {
	    Error3("mkfifo(%s, %d): %s", pipename, mode, strerror(errno));
	    return STAT_RETRYLATER;
	 }
#endif
	 Notice2("created named pipe \"%s\" for %s", pipename, ddirection[rw]);
	 applyopts_named(pipename, opts, PH_ALL);

      }
      if (opt_unlink_close) {
	 if ((fd->stream.unlink_close = strdup(pipename)) == NULL) {
	    Error1("strdup(\"%s\"): out of memory", pipename);
	 }
	 fd->stream.opt_unlink_close = true;
      }
   } else {
      /* exists */
      Debug1("xioopen_fifo(\"%s\"): already exist, opening it", pipename);
      Notice3("opening %s \"%s\" for %s",
	      filetypenames[(pipstat.st_mode&S_IFMT)>>12],
	      pipename, ddirection[rw]);
      /*applyopts_early(pipename, opts);*/
      applyopts_named(pipename, opts, PH_EARLY);
   }

   if ((result = _xioopen_open(pipename, rw, opts)) < 0) {
      return result;
   }
   fd->stream.fd = result;

   applyopts_named(pipename, opts, PH_FD);
   applyopts(fd->stream.fd, opts, PH_FD);
   applyopts_cloexec(fd->stream.fd, opts);
   return _xio_openlate(&fd->stream, opts);
}