Ejemplo n.º 1
0
/*
 * functions glob2 and glob3 are mutually recursive; there is one level
 * of recursion for each segment in the pattern that contains one or
 * more meta characters.
 */
static int
glob2(struct strbuf *pathbuf, const Char *pattern, glob_t *pglob, int no_match)
{
    struct stat sbuf;
    int anymeta;
    const Char *p;
    size_t orig_len;

    /*
     * loop over pattern segments until end of pattern or until segment with
     * meta character found.
     */
    anymeta = 0;
    for (;;) {
	if (*pattern == EOS) {	/* end of pattern? */
	    strbuf_terminate(pathbuf);

	    if (Lstat(pathbuf->s, &sbuf))
		return (0);

	    if (((pglob->gl_flags & GLOB_MARK) &&
		 pathbuf->s[pathbuf->len - 1] != SEP) &&
		(S_ISDIR(sbuf.st_mode)
#ifdef S_IFLNK
		 || (S_ISLNK(sbuf.st_mode) &&
		     (Stat(pathbuf->s, &sbuf) == 0) &&
		     S_ISDIR(sbuf.st_mode))
#endif
		 )) {
		strbuf_append1(pathbuf, SEP);
		strbuf_terminate(pathbuf);
	    }
	    ++pglob->gl_matchc;
	    globextend(pathbuf->s, pglob);
	    return 0;
	}

	/* find end of next segment, tentatively copy to pathbuf */
	p = pattern;
	orig_len = pathbuf->len;
	while (*p != EOS && *p != SEP) {
	    if (ismeta(*p))
		anymeta = 1;
	    strbuf_append1(pathbuf, *p++);
	}

	if (!anymeta) {		/* no expansion, do next segment */
	    pattern = p;
	    while (*pattern == SEP)
		strbuf_append1(pathbuf, *pattern++);
	}
	else {			/* need expansion, recurse */
	    pathbuf->len = orig_len;
	    return (glob3(pathbuf, pattern, p, pattern, pglob, no_match));
	}
    }
    /* NOTREACHED */
}
Ejemplo n.º 2
0
/* returns 0 if it could create lock; 1 if the lock exists; -1 on error */
int xiogetlock(const char *lockfile) {
   char *s;
   struct stat strat;
   int fd;
   pid_t pid;
   char pidbuf[3*sizeof(pid_t)+1];
   size_t bytes;

   if (Lstat(lockfile, &strat) == 0) {
      return 1;
   }
   switch (errno) {
   case ENOENT: break;
   default:
      Error3("Lstat(\"%s\", %p): %s", lockfile, &strat, strerror(errno));
      return -1;
   }
   /* in this moment, the file did not exist */

   if ((s = Malloc(strlen(lockfile)+8)) == NULL) {
      errno = ENOMEM;
      return -1;
   }
   strcpy(s, lockfile);
   strcat(s, ".XXXXXX");

   if ((fd = Mkstemp(s)) < 0) {
      Error2("mkstemp(\"%s\"): %s", s, strerror(errno));
      return -1;
   }
  
   pid = Getpid();
   bytes = sprintf(pidbuf, F_pid, pid);
   if (writefull(fd, pidbuf, bytes) < 0) {
      Error4("write(%d, %p, "F_Zu"): %s", fd, pidbuf, bytes, strerror(errno));
      return -1;
   }
   Close(fd);

   /* Chmod(lockfile, 0600); */
   if (Link(s, lockfile) < 0) {
      int _errno = errno;
      Error3("link(\"%s\", \"%s\"): %s", s, lockfile, strerror(errno));
      Unlink(s);
      errno = _errno;
      return -1;
   }
   Unlink(s);

   return 0;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/**
 * Check that file owner and group are known.
 * @param urlfn		file url
 * @return		RPMRC_OK on success
 */
static rpmRC checkOwners(const char * urlfn)
	/*@globals h_errno, fileSystem, internalState @*/
	/*@modifies fileSystem, internalState @*/
{
    struct stat sb;

    if (Lstat(urlfn, &sb)) {
	rpmlog(RPMLOG_ERR, _("Bad source: %s: %s\n"),
		urlfn, strerror(errno));
	return RPMRC_FAIL;
    }
    if (!getUname(sb.st_uid) || !getGname(sb.st_gid)) {
	rpmlog(RPMLOG_ERR, _("Bad owner/group: %s\n"), urlfn);
	return RPMRC_FAIL;
    }

    return RPMRC_OK;
}
Ejemplo n.º 5
0
static int
glob3(struct strbuf *pathbuf, const Char *pattern, const Char *restpattern,
      const Char *pglobstar, glob_t *pglob, int no_match)
{
    DIR    *dirp;
    struct dirent *dp;
    struct stat sbuf;
    int     err;
    Char m_not = (pglob->gl_flags & GLOB_ALTNOT) ? M_ALTNOT : M_NOT;
    size_t orig_len;
    int globstar = 0;
    int chase_symlinks = 0;
    const Char *termstar = NULL;

    strbuf_terminate(pathbuf);
    orig_len = pathbuf->len;
    errno = err = 0;

    while (pglobstar < restpattern) {
	__Char wc;
	size_t width = One_Char_mbtowc(&wc, pglobstar, MB_LEN_MAX);
	if ((pglobstar[0] & M_MASK) == M_ALL &&
	    (pglobstar[width] & M_MASK) == M_ALL) {
	    globstar = 1;
	    chase_symlinks = (pglobstar[2 * width] & M_MASK) == M_ALL;
	    termstar = pglobstar + (2 + chase_symlinks) * width;
	    break;
	}
        pglobstar += width;
    } 

    if (globstar) {
	err = pglobstar==pattern && termstar==restpattern ?
		*restpattern == EOS ?
		glob2(pathbuf, restpattern - 1, pglob, no_match) :
		glob2(pathbuf, restpattern + 1, pglob, no_match) :
		glob3(pathbuf, pattern, restpattern, termstar, pglob, no_match);
	if (err)
	    return err;
	pathbuf->len = orig_len;
	strbuf_terminate(pathbuf);
    }

    if (*pathbuf->s && (Lstat(pathbuf->s, &sbuf) || !S_ISDIR(sbuf.st_mode)
#ifdef S_IFLINK
	     && ((globstar && !chase_symlinks) || !S_ISLNK(sbuf.st_mode))
#endif
	))
	return 0;

    if (!(dirp = Opendir(pathbuf->s))) {
	/* todo: don't call for ENOENT or ENOTDIR? */
	if ((pglob->gl_errfunc && (*pglob->gl_errfunc) (pathbuf->s, errno)) ||
	    (pglob->gl_flags & GLOB_ERR))
	    return (GLOB_ABEND);
	else
	    return (0);
    }

    /* search directory for matching names */
    while ((dp = readdir(dirp)) != NULL) {
	/* initial DOT must be matched literally */
	if (dp->d_name[0] == DOT && *pattern != DOT)
	    if (!(pglob->gl_flags & GLOB_DOT) || !dp->d_name[1] ||
		(dp->d_name[1] == DOT && !dp->d_name[2]))
		continue; /*unless globdot and not . or .. */
	pathbuf->len = orig_len;
	strbuf_append(pathbuf, dp->d_name);
	strbuf_terminate(pathbuf);

	if (globstar) {
#ifdef S_IFLNK
	    if (!chase_symlinks &&
		(Lstat(pathbuf->s, &sbuf) || S_ISLNK(sbuf.st_mode)))
		    continue;
#endif
	    if (match(pathbuf->s + orig_len, pattern, termstar,
		(int)m_not) == no_match) 
		    continue;
	    strbuf_append1(pathbuf, SEP);
	    strbuf_terminate(pathbuf);
	    if ((err = glob2(pathbuf, pglobstar, pglob, no_match)) != 0)
		break;
	} else {
	    if (match(pathbuf->s + orig_len, pattern, restpattern,
		(int) m_not) == no_match)
		continue;
	    if ((err = glob2(pathbuf, restpattern, pglob, no_match)) != 0)
		break;
	}
    }
    /* todo: check error from readdir? */
    closedir(dirp);
    return (err);
}
Ejemplo n.º 6
0
/** \ingroup rpmcli
 * Verify file attributes (including file digest).
 * @param vf		file data to verify
 * #param spew		should verify results be printed?
 * @return		0 on success (or not installed), 1 on error
 */
static int rpmvfVerify(rpmvf vf, int spew)
	/*@globals h_errno, fileSystem, internalState @*/
	/*@modifies vf, fileSystem, internalState @*/
{
    rpmVerifyAttrs res = RPMVERIFY_NONE;
    struct stat sb;
    int ec = 0;

    /* Check to see if the file was installed - if not pretend all is OK. */
    switch (vf->fstate) {
    default:
    case RPMFILE_STATE_NETSHARED:
    case RPMFILE_STATE_REPLACED:
    case RPMFILE_STATE_NOTINSTALLED:
    case RPMFILE_STATE_WRONGCOLOR:
	goto exit;
	/*@notreached@*/ break;
    case RPMFILE_STATE_NORMAL:
	break;
    }

assert(vf->fn != NULL);
    if (vf->fn == NULL || Lstat(vf->fn, &sb) != 0) {
	res |= RPMVERIFY_LSTATFAIL;
	ec = 1;
	goto exit;
    }

    /* Not all attributes of non-regular files can be verified. */
    if (S_ISDIR(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else if (S_ISLNK(sb.st_mode)) {
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
		RPMVERIFY_MODE | RPMVERIFY_HMAC);
#if CHOWN_FOLLOWS_SYMLINK
	vf->vflags &= ~(RPMVERIFY_USER | RPMVERIFY_GROUP);
#endif
    }
    else if (S_ISFIFO(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else if (S_ISCHR(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else if (S_ISBLK(sb.st_mode))
	vf->vflags &= ~(RPMVERIFY_FDIGEST | RPMVERIFY_FILESIZE | RPMVERIFY_MTIME |
			RPMVERIFY_LINKTO | RPMVERIFY_HMAC);
    else
	vf->vflags &= ~(RPMVERIFY_LINKTO);

    if (vf->vflags & (RPMVERIFY_FDIGEST | RPMVERIFY_HMAC)) {
	if (vf->digest == NULL || vf->dlen == 0)
	    res |= RPMVERIFY_FDIGEST;
	else {
	/* XXX If --nofdigest, then prelinked library sizes fail to verify. */
	    unsigned char * fdigest = memset(alloca(vf->dlen), 0, vf->dlen);
	    size_t fsize = 0;
#define	_mask	(RPMVERIFY_FDIGEST|RPMVERIFY_HMAC)
	    unsigned dflags = (vf->vflags & _mask) == RPMVERIFY_HMAC
		? 0x2 : 0x0;
#undef	_mask
	    int rc = dodigest(vf->dalgo, vf->fn, fdigest, dflags, &fsize);
	    sb.st_size = fsize;
	    if (rc)
		res |= (RPMVERIFY_READFAIL|RPMVERIFY_FDIGEST);
	    else
	    if (memcmp(fdigest, vf->digest, vf->dlen))
		res |= RPMVERIFY_FDIGEST;
	}
    }

    if (vf->vflags & RPMVERIFY_LINKTO) {
	char linkto[1024+1];
	int size = 0;

	if ((size = Readlink(vf->fn, linkto, sizeof(linkto)-1)) == -1)
	    res |= (RPMVERIFY_READLINKFAIL|RPMVERIFY_LINKTO);
	else {
	    linkto[size] = '\0';
	    if (vf->flink == NULL || strcmp(linkto, vf->flink))
		res |= RPMVERIFY_LINKTO;
	}
    }

    if (vf->vflags & RPMVERIFY_FILESIZE) {
	if (sb.st_size != vf->sb.st_size)
	    res |= RPMVERIFY_FILESIZE;
    }

    if (vf->vflags & RPMVERIFY_MODE) {
	/* XXX AIX has sizeof(mode_t) > sizeof(unsigned short) */
	unsigned short metamode = (unsigned short)vf->sb.st_mode;
	unsigned short filemode = (unsigned short)sb.st_mode;

	/* Comparing type of %ghost files is meaningless, but perms are OK. */
	if (vf->fflags & RPMFILE_GHOST) {
	    metamode &= ~0xf000;
	    filemode &= ~0xf000;
	}
	if (metamode != filemode)
	    res |= RPMVERIFY_MODE;
    }

    if (vf->vflags & RPMVERIFY_RDEV) {
	if (S_ISCHR(vf->sb.st_mode) != S_ISCHR(sb.st_mode)
	 || S_ISBLK(vf->sb.st_mode) != S_ISBLK(sb.st_mode))
	    res |= RPMVERIFY_RDEV;
	else if (S_ISDEV(vf->sb.st_mode) && S_ISDEV(sb.st_mode)) {
	    rpmuint16_t st_rdev = (rpmuint16_t)(sb.st_rdev & 0xffff);
	    rpmuint16_t frdev = (rpmuint16_t)(vf->sb.st_rdev & 0xffff);
	    if (st_rdev != frdev)
		res |= RPMVERIFY_RDEV;
	}
    }

    if (vf->vflags & RPMVERIFY_MTIME) {
	if (sb.st_mtime != vf->sb.st_mtime)
	    res |= RPMVERIFY_MTIME;
    }

    if (vf->vflags & RPMVERIFY_USER) {
	const char * fuser = uidToUname(sb.st_uid);
	if (fuser == NULL || vf->fuser == NULL || strcmp(fuser, vf->fuser))
	    res |= RPMVERIFY_USER;
    }

    if (vf->vflags & RPMVERIFY_GROUP) {
	const char * fgroup = gidToGname(sb.st_gid);
	if (fgroup == NULL || vf->fgroup == NULL || strcmp(fgroup, vf->fgroup))
	    res |= RPMVERIFY_GROUP;
    }

exit:

    if (spew) {	/* XXX no output w verify(...) probe. */
	char buf[BUFSIZ];
	char * t = buf;
	char * te = t;
	*te = '\0';
	if (ec) {
	    if (!(vf->fflags & (RPMFILE_MISSINGOK|RPMFILE_GHOST))
	     || rpmIsVerbose())
	    {
		sprintf(te, _("missing   %c %s"),
			((vf->fflags & RPMFILE_CONFIG)	? 'c' :
			 (vf->fflags & RPMFILE_DOC)	? 'd' :
			 (vf->fflags & RPMFILE_GHOST)	? 'g' :
			 (vf->fflags & RPMFILE_LICENSE)	? 'l' :
			 (vf->fflags & RPMFILE_PUBKEY)	? 'P' :
			 (vf->fflags & RPMFILE_README)	? 'r' : ' '),
			vf->fn);
                if ((res & RPMVERIFY_LSTATFAIL) != 0 && errno != ENOENT) {
		    te += strlen(te);
                    sprintf(te, " (%s)", strerror(errno));
                }
	    }
	} else if (res || rpmIsVerbose()) {
	    /*@observer@*/ static const char aok[] = ".";
	    /*@observer@*/ static const char unknown[] = "?";

#define	_verify(_RPMVERIFY_F, _C)	\
	((res & _RPMVERIFY_F) ? _C : aok)
#define	_verifylink(_RPMVERIFY_F, _C)	\
	((res & RPMVERIFY_READLINKFAIL) ? unknown : \
	 (res & _RPMVERIFY_F) ? _C : aok)
#define	_verifyfile(_RPMVERIFY_F, _C)	\
	((res & RPMVERIFY_READFAIL) ? unknown : \
	 (res & _RPMVERIFY_F) ? _C : aok)
	
	    const char * digest = _verifyfile(RPMVERIFY_FDIGEST, "5");
	    const char * size = _verify(RPMVERIFY_FILESIZE, "S");
	    const char * link = _verifylink(RPMVERIFY_LINKTO, "L");
	    const char * mtime = _verify(RPMVERIFY_MTIME, "T");
	    const char * rdev = _verify(RPMVERIFY_RDEV, "D");
	    const char * user = _verify(RPMVERIFY_USER, "U");
	    const char * group = _verify(RPMVERIFY_GROUP, "G");
	    const char * mode = _verify(RPMVERIFY_MODE, "M");

#undef _verifyfile
#undef _verifylink
#undef _verify

	    sprintf(te, "%s%s%s%s%s%s%s%s  %c %s",
		    size, mode, digest, rdev, link, user, group, mtime,
			((vf->fflags & RPMFILE_CONFIG)	? 'c' :
			 (vf->fflags & RPMFILE_DOC)	? 'd' :
			 (vf->fflags & RPMFILE_GHOST)	? 'g' :
			 (vf->fflags & RPMFILE_LICENSE)	? 'l' :
			 (vf->fflags & RPMFILE_PUBKEY)	? 'P' :
			 (vf->fflags & RPMFILE_README)	? 'r' : ' '),
			vf->fn);

	}

	if (t && *t)
	    rpmlog(RPMLOG_NOTICE, "%s\n", t);

    }

    return (res != 0);
}
Ejemplo n.º 7
0
static
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
		      int xioflags, xiofile_t *xxfd, unsigned groups,
		      int abstract, int dummy2, int dummy3) {
   /* we expect the form: filename */
   const char *name;
   xiosingle_t *xfd = &xxfd->stream;
   int pf = PF_UNIX;
   int socktype = SOCK_DGRAM;
   int protocol = 0;
   union sockaddr_union us;
   socklen_t uslen;
   bool tight = true;
   bool opt_unlink_early = false;
   bool opt_unlink_close = true;
   int result;

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

   name = argv[1];
   retropt_socket_pf(opts, &pf);
   retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
   uslen = xiosetunix(pf, &us.un, name, abstract, tight);

#if 1	/*!!! why bind option? */
   retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 1, 0, 0);
#endif

   if (!(ABSTRACT && abstract)) {
      /* only for non abstract because abstract do not work in file system */
      retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
      retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);

      if (opt_unlink_early) {
	 if (Unlink(name) < 0) {
	    if (errno == ENOENT) {
	       Warn2("unlink(\"%s\"): %s", name, strerror(errno));
	    } else {
	       Error2("unlink(\"%s\"): %s", name, strerror(errno));
	    }
	 }
      } else {
	 struct stat buf;
	 if (Lstat(name, &buf) == 0) {
	    Error1("\"%s\" exists", name);
	    return STAT_RETRYLATER;
	 }
      }
      if (opt_unlink_close) {
	 if ((xfd->unlink_close = strdup(name)) == NULL) {
	    Error1("strdup(\"%s\"): out of memory", name);
	 }
	 xfd->opt_unlink_close = true;
      }
   }
   applyopts_named(name, opts, PH_EARLY);	/* umask! */

   xfd->para.socket.la.soa.sa_family = pf;

   xfd->dtype = XIODATA_RECV;
   result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen,
				opts, pf, socktype, protocol, E_ERROR);
   return result;
}
Ejemplo n.º 8
0
static
int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
		     int xioflags, xiofile_t *xxfd, unsigned groups,
		     int abstract, int dummy2, int dummy3) {
   /* we expect the form: filename */
   const char *name;
   xiosingle_t *xfd = &xxfd->stream;
   int pf = PF_UNIX;
   int socktype = SOCK_DGRAM;
   int protocol = 0;
   struct sockaddr_un us;
   socklen_t uslen;
   bool tight = true;
   bool needbind = true;
   bool opt_unlink_early = false;
   bool opt_unlink_close = true;

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

   name = argv[1];
   retropt_socket_pf(opts, &pf);
   retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
   uslen = xiosetunix(pf, &us, name, abstract, tight);

   xfd->howtoend = END_NONE;
   retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
		1, 0, 0);

   if (!(ABSTRACT && abstract)) {
      /* only for non abstract because abstract do not work in file system */
      retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
      retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
   }

   if (!(ABSTRACT && abstract)) {
      if (opt_unlink_early) {
	 if (Unlink(name) < 0) {
	    if (errno == ENOENT) {
	       Warn2("unlink(\"%s\"): %s", name, strerror(errno));
	    } else {
	       Error2("unlink(\"%s\"): %s", name, strerror(errno));
	    }
	 }
      } else {
	 struct stat buf;
	 if (Lstat(name, &buf) == 0) {
	    Error1("\"%s\" exists", name);
	    return STAT_RETRYLATER;
	 }
      }
      if (opt_unlink_close) {
	 if ((xfd->unlink_close = strdup(name)) == NULL) {
	    Error1("strdup(\"%s\"): out of memory", name);
	 }
	 xfd->opt_unlink_close = true;
      }

      /* trying to set user-early, perm-early etc. here is useless because
	 file system entry is available only past bind() call. */
   }
   applyopts_named(name, opts, PH_EARLY);	/* umask! */

   xfd->para.socket.la.soa.sa_family = pf;

   xfd->dtype = XIODATA_RECVFROM_ONE;

   /* this may fork */
   return
      _xioopen_dgram_recvfrom(xfd, xioflags,
			      needbind?(struct sockaddr *)&us:NULL, uslen,
			      opts, pf, socktype, protocol, E_ERROR);
}
Ejemplo n.º 9
0
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) {
   /* we expect the form: filename */
   const char *name;
   xiosingle_t *xfd = &xxfd->stream;
   int pf = PF_UNIX;
   int socktype = SOCK_STREAM;
   int protocol = 0;
   struct sockaddr_un us;
   socklen_t uslen;
   bool tight = true;
   struct opt *opts0 = NULL;
   pid_t pid = Getpid();
   bool opt_unlink_early = false;
   bool opt_unlink_close = true;
   int result;

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

   name = argv[1];
   retropt_socket_pf(opts, &pf);
   retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
   uslen = xiosetunix(pf, &us, name, abstract, tight);

   xfd->howtoend = END_SHUTDOWN;

   if (!(ABSTRACT && abstract)) {
      /* only for non abstract because abstract do not work in file system */
      retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
      retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
   }

   if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
   applyopts(-1, opts, PH_INIT);
   applyopts_named(name, opts, PH_EARLY);	/* umask! */
   applyopts(-1, opts, PH_EARLY);

   if (!(ABSTRACT && abstract)) {
      if (opt_unlink_early) {
	 if (Unlink(name) < 0) {
	    if (errno == ENOENT) {
	       Warn2("unlink(\"%s\"): %s", name, strerror(errno));
	    } else {
	       Error2("unlink(\"%s\"): %s", name, strerror(errno));
	    }
	 }
      } else {
	 struct stat buf;
	 if (Lstat(name, &buf) == 0) {
	    Error1("\"%s\" exists", name);
	    return STAT_RETRYLATER;
	 }
      }
      if (opt_unlink_close) {
	 if ((xfd->unlink_close = strdup(name)) == NULL) {
	    Error1("strdup(\"%s\"): out of memory", name);
	 }
	 xfd->opt_unlink_close = true;
      }

      /* trying to set user-early, perm-early etc. here is useless because
	 file system entry is available only past bind() call. */
   }

   opts0 = copyopts(opts, GROUP_ALL);

   /* this may fork() */
   if ((result =
	xioopen_listen(xfd, xioflags,
		       (struct sockaddr *)&us, uslen,
		       opts, opts0, pf, socktype, protocol))
       != 0)
      return result;

   if (!(ABSTRACT && abstract)) {
      if (opt_unlink_close) {
	 if (pid != Getpid()) {
	    /* in a child process - do not unlink-close here! */
	    xfd->opt_unlink_close = false;
	 }
      }
   }

   return 0;
}
Ejemplo n.º 10
0
static int
FtwTraverse(const FtwInfoPtr ftwip, size_t dirPathLen, int depth)
{
    DIR *DIRp;
    char *cp;
    size_t fnLen;
    struct dirent *dentp;
    mode_t m;
    char *filename;
    char *newBuf;
    char *path = ftwip->curPath;
    int nSubdirs;
    FtwSubDirListPtr head = NULL, tail = NULL, sdp, nextsdp;
    int rc = (-1);
    int isRootDir;

    isRootDir = ((dirPathLen == 1) && (IsLocalPathDelim(path[0]))) ? 1 : 0;
    if ((DIRp = opendir(dirPathLen ? path : ".")) == NULL)
    {
        /* Not an error unless the first directory could not be opened. */
        return (0);
    }

    nSubdirs = 0;
    ++ftwip->numDirs;
    ftwip->depth = depth;
    if (ftwip->maxDepth < ftwip->depth)
    {
        ftwip->maxDepth = ftwip->depth;
    }
    filename = path + dirPathLen;
    if (isRootDir == 0)  	/* Root directory is a separator. */
    {
        *filename++ = (char) ftwip->dirSeparator;
        dirPathLen++;
    }
    *filename = '\0';
    /* Path now contains dir/  */

    dentp = (struct dirent *) ftwip->direntbuf;
    for (;;)
    {
        if (Readdir(DIRp, dentp, ftwip->direntbufSize) == NULL)
            break;
        cp = dentp->d_name;
        if ((cp[0] == '.') && ((cp[1] == '\0') || ((cp[1] == '.') && (cp[2] == '\0'))))
            continue;	/* Skip . and .. */

        *filename = '\0';
        fnLen = strlen(cp) + 1	/* include \0 */;
        if ((fnLen + dirPathLen) > ftwip->curPathAllocSize)
        {
            if (ftwip->autoGrow == kFtwNoAutoGrowAndFail)
            {
                goto panic;
            }
            else if (ftwip->autoGrow == kFtwNoAutoGrowButContinue)
            {
                continue;
            }
            newBuf = (char *) realloc(ftwip->curPath, fnLen + dirPathLen + 30 + 2 /* room for / and \0 */);
            if (newBuf == NULL)
                goto panic;
            ftwip->curPath = newBuf;
            ftwip->curPathAllocSize = fnLen + dirPathLen + 30;
            path = ftwip->curPath;
            filename = path + dirPathLen;
            if (isRootDir == 0)	/* Root directory is a separator. */
                *filename++ = (char) ftwip->dirSeparator;
            *filename = '\0';
        }
        memcpy(filename, cp, fnLen);
        ftwip->curPathLen = dirPathLen + fnLen - 1;
        ftwip->curFile = filename;
        ftwip->curFileLen = fnLen - 1;
        if (Lstat(path, &ftwip->curStat) == 0)
        {
            m = ftwip->curStat.st_mode;
            if (S_ISREG(m))
            {
                ++ftwip->numFiles;
                ftwip->curType = '-';
                if ((*ftwip->proc)(ftwip) < 0)
                {
                    goto panic;
                }
#ifdef S_ISLNK
            }
            else if (S_ISLNK(m))
            {
                ftwip->curType = 'l';
                ++ftwip->numLinks;
                if ((*ftwip->proc)(ftwip) < 0)
                {
                    goto panic;
                }
#endif	/* S_ISLNK */
            }
            else if (S_ISDIR(m))
            {
                /* We delay entering the subdirectories
                 * until we have closed this directory.
                 * This will conserve file descriptors
                 * and also have the effect of having
                 * the files processed first.
                 */
                sdp = (FtwSubDirListPtr) malloc(sizeof(FtwSubDirList) + fnLen);
                if (sdp == NULL)
                    goto panic;
                memcpy(&sdp->st, &ftwip->curStat, sizeof(sdp->st));
                memcpy(sdp->name, cp, fnLen);
                sdp->fnLen = fnLen;
                sdp->next = NULL;
                if (head == NULL)
                {
                    head = tail = sdp;
                }
                else
                {
                    tail->next = sdp;
                    tail = sdp;
                }
                nSubdirs++;
            }
        }
    }
    (void) closedir(DIRp);
    DIRp = NULL;

    /* Now enter each subdirectory. */
    for (sdp = head; sdp != NULL; sdp = nextsdp)
    {
        nextsdp = sdp->next;
        memcpy(&ftwip->curStat, &sdp->st, sizeof(ftwip->curStat));
        fnLen = sdp->fnLen;
        memcpy(filename, sdp->name, fnLen);
        ftwip->curPathLen = dirPathLen + fnLen - 1;
        ftwip->curFile = filename;
        ftwip->curFileLen = fnLen - 1;
        head = nextsdp;
        free(sdp);

        ftwip->curType = 'd';
        if ((*ftwip->proc)(ftwip) < 0)
        {
            goto panic;
        }
        if (FtwTraverse(ftwip, dirPathLen + fnLen - 1, depth + 1) < 0)
            goto panic;

        /* Reset these, since buffer could have
         * been reallocated.
         */
        path = ftwip->curPath;
        filename = path + dirPathLen;
        *filename = '\0';
    }
    head = NULL;
    rc = 0;

panic:
    if (DIRp != NULL)
        (void) closedir(DIRp);

    for (sdp = head; sdp != NULL; sdp = nextsdp)
    {
        nextsdp = sdp->next;
        free(sdp);
    }

    return (rc);
}	/* FtwTraverse */
Ejemplo n.º 11
0
/**
 * Check that all sources/patches/icons exist locally, fetching if necessary.
 */
static int prepFetch(Spec spec)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
{
#if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
    const char *Smacro;
#endif
    const char *Lmacro, *Lurlfn = NULL;
    const char *Rmacro, *Rurlfn = NULL;
    struct Source *sp;
    struct stat st;
    rpmRC rpmrc;
    int ec, rc;
    char *cp;

    /* XXX insure that %{_sourcedir} exists */
    rpmrc = RPMRC_OK;
    Lurlfn = rpmGenPath(NULL, "%{?_sourcedir}", NULL);
    if (Lurlfn != NULL && *Lurlfn != '\0')
	rpmrc = rpmMkdirPath(Lurlfn, "_sourcedir");
    Lurlfn = _free(Lurlfn);
    if (rpmrc != RPMRC_OK)
	return -1;

    /* XXX insure that %{_patchdir} exists */
    rpmrc = RPMRC_OK;
    Lurlfn = rpmGenPath(NULL, "%{?_patchdir}", NULL);
    if (Lurlfn != NULL && *Lurlfn != '\0')
	rpmrc = rpmMkdirPath(Lurlfn, "_patchdir");
    Lurlfn = _free(Lurlfn);
    if (rpmrc != RPMRC_OK)
	return -1;

    /* XXX insure that %{_icondir} exists */
    rpmrc = RPMRC_OK;
    Lurlfn = rpmGenPath(NULL, "%{?_icondir}", NULL);
    if (Lurlfn != NULL && *Lurlfn != '\0')
	rpmrc = rpmMkdirPath(Lurlfn, "_icondir");
    Lurlfn = _free(Lurlfn);
    if (rpmrc != RPMRC_OK)
	return -1;

    if (rpmIsVerbose() && !quietly && (rpmBTArgs.buildAmount & RPMBUILD_FETCHSOURCE))
        rpmlog(RPMLOG_NOTICE, "Checking source and patch file(s):\n");

    ec = 0;
    for (sp = spec->sources; sp != NULL; sp = sp->next) {

#if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
	Smacro = "%{?_specdir}/";
#endif
#if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
    if (! (Lmacro = getSourceDir(sp->flags, sp->source)))
#else
    if (! (Lmacro = getSourceDir(sp->flags)))
#endif
        continue;
	if (sp->flags & RPMFILE_SOURCE) {
	    Rmacro = "%{?_Rsourcedir}/";
	} else
	if (sp->flags & RPMFILE_PATCH) {
	    Rmacro = "%{?_Rpatchdir}/";
	} else
	if (sp->flags & RPMFILE_ICON) {
	    Rmacro = "%{?_Ricondir}/";
	} else
	    continue;

#if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
	/* support splitted source directories, i.e., source files which
	   are alternatively placed into the .spec directory and picked
	   up from there, too. */
	Lurlfn = rpmGenPath(NULL, Smacro, sp->source);
	rc = Lstat(Lurlfn, &st);
	if (rc == 0) {
            prepFetchVerbose(sp, &st);
	    goto bottom;
        }
#endif
	Lurlfn = rpmGenPath(NULL, Lmacro, sp->source);
	rc = Lstat(Lurlfn, &st);
	if (rc == 0) {
/*@-noeffect@*/
            prepFetchVerbose(sp, &st);
/*@=noeffect@*/
	    goto bottom;
        }
/*@-noeffect@*/
        prepFetchVerbose(sp, NULL);
/*@=noeffect@*/
	if (errno != ENOENT) {
	    ec++;
	    rpmlog(RPMLOG_ERR, _("Missing %s%d %s: %s\n"),
		((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"),
		sp->num, sp->source, strerror(ENOENT));
	    goto bottom;
	}

        /* try to fetch via macro-controlled remote locations */
        cp = rpmExpand(Rmacro, NULL);
        if (cp != NULL && strcmp(cp, "/") != 0) {
            cp = _free(cp);
            Rurlfn = rpmGenPath(NULL, Rmacro, sp->source);
            if (!(Rurlfn == NULL || Rurlfn[0] == '\0' || !strcmp(Rurlfn, "/") || !strcmp(Lurlfn, Rurlfn))) {
                rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"),
                       (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, Rurlfn);
                rc = urlGetFile(Rurlfn, Lurlfn);
                if (rc == 0)
                    goto bottom;
                else {
                    rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"),
                           (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc));
                    ec++;
                }
            }
        }
        cp = _free(cp);

        /* try to fetch from original location */
        rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"),
               (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, sp->fullSource);
        rc = urlGetFile(sp->fullSource, Lurlfn);
        if (rc == 0)
            goto bottom;
        else {
            rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"),
                   (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc));
            ec++;
        }

        rpmlog(RPMLOG_ERR, _("Missing %s%d: %s: %s\n"),
            ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"),
            sp->num, sp->source, strerror(ENOENT));
        ec++;

bottom:
	Lurlfn = _free(Lurlfn);
	Rurlfn = _free(Rurlfn);
    }

    return ec;
}