Пример #1
0
str
trunc_at_first_null (const str &s)
{
  assert (s);

  const char *cp;
  size_t len = s.len ();
  size_t l;
  const char nullc = '\0';

  // Figure out if a '\0' or the end-of-string comes first.
  for (cp = s.cstr (), l = 0; *cp != nullc && l < len; cp++, l++);

  str ret;

  if (*cp == nullc) {
    
    // The most likely outcome
    if (l == len) ret = s;

    // There was a '\0' inside the string
    else ret = s.cstr ();

  } else {
   
    // String is not null terminated!
    mstr m (len + 1);
    memcpy (m.cstr (), s.cstr (), len);
    m[len] = nullc;
    ret = m;
  }

  return ret;
}
Пример #2
0
void
dhblock_keyhash_srv::real_store (chordID key, str od, str nd, u_int32_t exp, cb_dhstat cb)
{
  u_int32_t v1 = dhblock_keyhash::version (nd.cstr (), nd.len ());
  if (od.len ()) {
    u_int32_t v0 = dhblock_keyhash::version (od.cstr (), od.len ());
    if (v0 > v1) {
      chordID p = node->my_pred ()->id ();
      chordID m = node->my_ID ();
      if (betweenrightincl (p, m, key))
	cb (DHASH_STALE);
      else
	cb (DHASH_RETRY);
    } else {
      info << "db delete: " << key << "\n";
      db->remove (key, v0, 
		  wrap (this, &dhblock_keyhash_srv::delete_cb, key, 
			nd, v1, exp, cb));
    }
  } else {
    info << "db write: " << node->my_ID ()
	 << " N " << key << " " << nd.len () << "\n";
    db_store (key, nd, v1, exp, cb);
  }
}
Пример #3
0
wide_str_t::wide_str_t (str utf8_in)
{
  if (utf8_in) {
    _init (utf8_in.len ());
    mbstate_t state;
    memset (&state, 0, sizeof (state));
    const char *src = utf8_in.cstr ();
    setlocale (LC_CTYPE, "en_US.UTF-8");
    ssize_t ret = mbstowcs (_buf->base (), src, _buf->size ());
    if (ret < 0) {
      _err = true;
      _buf = NULL;
      _len = 0;
    } else {
      _len = ret;
      if (0 && src) {
	warn << "XX failed to completely convert string ('" 
	     << utf8_in << "'): " 
	     << "expected " << _len << " bytes, but only converted "
	     << (src - utf8_in.cstr ()) << "\n";
	_err = true;
      } else {
	_err = false;
      }
    }
  }
}
Пример #4
0
bool
can_read (const str &f)
{
  struct stat sb;
  return  (f && stat(f.cstr (), &sb) == 0 && S_ISREG (sb.st_mode)
	   && access (f.cstr(), R_OK) == 0);
}
Пример #5
0
/* If the directory specified by path does not exist, create it with
 * the given mode. If we fail for any reason, terminate with error.  */
void
mksfsdir (str path, mode_t mode, struct stat *sbp, uid_t uid)
{
  assert (path[0] == '/');

  mode_t m = umask (0);
  struct stat sb;
  if (stat (path, &sb) < 0) {
    if (errno != ENOENT || (mkdir (path, mode) < 0 && errno != EEXIST))
      fatal ("%s: %m\n", path.cstr ());
    if (chown (path, uid, sfs_gid) < 0) {
      int saved_errno = errno;
      rmdir (path);
      fatal ("chown (%s): %s\n", path.cstr (), strerror (saved_errno));
    }
    if (stat (path, &sb) < 0)
      fatal ("stat (%s): %m\n", path.cstr ());
  }
  umask (m);

  if (!S_ISDIR (sb.st_mode))
    fatal ("%s: not a directory\n", path.cstr ());
  if (sb.st_uid != uid)
    fwarn << path << ": owned by uid " << sb.st_uid
	  << ", should be uid " << uid << "\n";
  if (sb.st_gid != sfs_gid)
    fwarn << path << ": has gid " << sb.st_gid
	  << ", should be gid " << sfs_gid << "\n";
  if (sb.st_mode & 07777 & ~mode)
    fwarn ("%s: mode 0%o, should be 0%o\n",
	   path.cstr (), int (sb.st_mode & 07777), int (mode));

  if (sbp)
    *sbp = sb;
}
Пример #6
0
int
suidgetfd_required (str prog)
{
  int fds[2];
  if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
    fatal ("socketpair: %m\n");
  close_on_exec (fds[0]);

  str path = fix_exec_path ("suidconnect");
  char *av[] = { "suidconnect", const_cast<char *> (prog.cstr ()), NULL };
  if (spawn (path, av, fds[1]) == -1)
    fatal << path << ": " << strerror (errno) << "\n";
  close (fds[1]);
  
  int fd = recvfd (fds[0]);
  if (fd < 0) {
    struct stat sb;
    if (!runinplace && !stat (path, &sb)
	&& (sb.st_gid != sfs_gid || !(sb.st_mode & 02000))) {
      if (struct group *gr = getgrgid (sfs_gid))
	warn << path << " should be setgid to group " << gr->gr_name << "\n";
      else
	warn << path << " should be setgid to group " << sfs_gid << "\n";
    }
    else {
      warn << "have you launched the appropriate daemon (sfscd or sfssd)?\n";
      warn << "have subsidiary daemons died (check your system logs)?\n";
    }
    fatal ("could not suidconnect for %s\n", prog.cstr ());
  }
  close (fds[0]);
  return fd;
}
Пример #7
0
static void
idlookup (str uid, str gid)
{
  if (!uid)
    uid = "sfs";
  if (!gid)
    gid = uid;

  bool uidok = convertint (uid, &sfs_uid);
  struct passwd *pw = uidok ? getpwuid (sfs_uid) : getpwnam (uid.cstr ());
  bool gidok = convertint (gid, &sfs_gid);
  struct group *gr = gidok ? getgrgid (sfs_gid) : getgrnam (gid.cstr ());

  if (!uidok) {
    if (!pw)
      fatal << "Could not find user " << uid << "\n";
    sfs_uid = pw->pw_uid;
  }
  if (!gidok) {
    if (!gr)
      fatal << "Could not find group " << gid << "\n";
    sfs_gid = gr->gr_gid;
  }
  if (gr && gr->gr_mem[0])
    fwarn << "Group " << gid << " must not have any members\n";
  if (pw && gr && (gid_t) pw->pw_gid != (gid_t) gr->gr_gid)
    fwarn << "User " << uid << " must have login group " << gid << ".\n";

  endpwent ();
  endgrent ();
}
Пример #8
0
bool
isdir (const str &d)
{
  struct stat sb;
  return (!stat (d.cstr(), &sb)
          && (sb.st_mode & S_IFDIR)
          && !access (d.cstr(), X_OK|R_OK));
}
inline str
group_prefix (str s, str prefix)
{
  if (s.len () <= prefix.len () || s[prefix.len ()] != '.'
      || memcmp (s.cstr (), prefix.cstr (), prefix.len ()))
    return NULL;
  return substr (s, prefix.len () + 1);
}
Пример #10
0
str
can_exec (const str &p)
{
  if (access (p.cstr (), R_OK)) 
    return ("cannot read executable");
  else if (access (p.cstr (), X_OK)) 
    return ("cannot execute");
  return NULL;
}
Пример #11
0
u_int count_newlines (str s)
{
  const char *end = s.cstr () + s.len ();
  u_int c = 0;
  for (const char *cp = s.cstr (); cp < end; cp++) {
    if (*cp == '\n')
      c++;
  }
  return c;
}
Пример #12
0
void
suio_print (suio *uio, const str &s)
{
  if (s.len () <= suio::smallbufsize)
    uio->copy (s.cstr (), s.len ());
  else {
    uio->print (s.cstr (), s.len ());
    uio->iovcb (wrap (&s.b.Xplug, s.b.Xleak ()));
  }
}
Пример #13
0
str
trunc_after_null_byte (str s)
{
  str ret;
  size_t l;
  if (!s) { ret = s; }
  else if ((l = strlen (s.cstr())) == s.len ()) { ret = s; }
  else { ret = str (s.cstr (), l); }
  return ret;
}
Пример #14
0
void
random_set_seedfile (str path)
{
  if (!path) {
    if (seed) {
      munmap (reinterpret_cast<char *> (seed), mapsize);
      seed = NULL;
    }
    return;
  }

  if (path[0] == '~' && path[1] == '/') {
    const char *home = getenv ("HOME");
    if (!home) {
      warn ("$HOME not set in environment\n");
      return;
    }
    path = strbuf () << home << (path.cstr () + 1);
  }

  int fd = open (path, O_CREAT|O_RDWR, 0600);
  if (fd < 0) {
    warn ("%s: %m\n", path.cstr ());
    return;
  }
  struct stat sb;
  char c;
  if (read (fd, &c, 1) < 0 || fstat (fd, &sb) < 0
      || lseek (fd, mapsize - 1, SEEK_SET) == -1
      || write (fd, "", 1) < 0) {
    /* The read call avoids a segfault on NFS 2.  Specifically, if we
     * are root and the random_seed file is over NFS 2, the open will
     * succeed even though read returns EACCES.  If we map the file
     * when we can't read it--bingo, segfault.  (In fact, on some OSes
     * it also seems to cause a kernel panic when you examine the
     * mmapped memory from the debugger.) */
    close (fd);
    warn ("%s: %m\n", path.cstr ());
    return;
  }
  if ((sb.st_mode & 07777) != 0600)
    warn ("%s: mode 0%o should be 0600\n", path.cstr (), sb.st_mode & 07777);

  if (seed)
    munmap (reinterpret_cast<char *> (seed), mapsize);
  seed = mmap (NULL, (size_t) mapsize, PROT_READ|PROT_WRITE,
	       MAP_FILE|MAP_SHARED, fd, 0);
  if (seed == reinterpret_cast<void *> (MAP_FAILED)) {
    warn ("mmap: %s: %m\n", path.cstr ());
    seed = NULL;
  }
  else
    rnd_input.update (seed, seedsize);
  close (fd);
}
Пример #15
0
int
open_file (const str &nm, int flags)
{
  char *s = strdup (nm.cstr ());
  int rc = 0;

  rc = mkdir_p (s);
  if (rc == 0)
    rc = ::open (nm.cstr (), flags, 0666);

  if (s) free (s);
  return rc;
}
Пример #16
0
int
start_logger (const str &priority, const str &tag, const str &line, 
	      const str &logfile, int flags, mode_t mode)
{
  str logger;
#ifdef PATH_LOGGER
  logger = PATH_LOGGER;
#endif

  if (logger) {
    const char *av[] = { NULL, "-p", NULL, "-t", NULL, NULL, NULL };
    av[0] = const_cast<char *> (logger.cstr ());
    av[2] = const_cast<char *> (priority.cstr ());
  
    if (line)
      av[5] = const_cast<char *> (line.cstr ());
    else
      av[5] = "log started";
    
    if (tag)
      av[4] = const_cast<char *> (tag.cstr ());
    else 
      av[4] = "";
    
    pid_t pid;
    int status;
    if ((pid = spawn (av[0], av, 0, 0, errfd)) < 0) {
      warn ("%s: %m\n", logger.cstr ());
      return start_log_to_file (line, logfile, flags, mode);
    } 
    if (waitpid (pid, &status, 0) <= 0 || !WIFEXITED (status) || 
	WEXITSTATUS (status)) 
      return start_log_to_file (line, logfile, flags, mode);
    
    int fds[2];
    if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
      fatal ("socketpair: %m\n");
    close_on_exec (fds[0]);
    if (fds[1] != 0)
      close_on_exec (fds[1]);
    
    av[5] = NULL;
    if (spawn (av[0], av, fds[1], 0, 0) >= 0) {
      close (fds[1]);
      return fds[0];
    } else {
      warn ("%s: %m\n", logger.cstr ());
    }
  } 
  return start_log_to_file (line, logfile, flags, mode);
}
Пример #17
0
static str
makehdrname (str fname)
{
  strbuf hdr;
  const char *p;

  if ((p = strrchr (fname.cstr(), '/')))
    p++;
  else p = fname.cstr();

  hdr.buf (p, strlen (p) - 1);
  hdr.cat ("h");

  return hdr;
}
Пример #18
0
void
dhashclient::retrieve (bigint key, dhash_ctype ct, cb_cret cb, str& data,
		       ptr<option_block> options)
{
  ref<dhash_retrieve_res> res = New refcounted<dhash_retrieve_res> (DHASH_OK);
  dhash_retrieve_arg arg;
  arg.blockID = key;
  arg.ctype = ct;
  arg.options = 0;
  if (options) {
    arg.options = options->flags;
    if (options->flags & DHASHCLIENT_GUESS_SUPPLIED) {
      arg.guess = options->guess;
      //warn << "starting with guess: " << arg.guess << "\n";
      //warn << "using guess\n";
		}
  }

	// Praveen
	if (data.len()) {
  	arg.data.setsize (data.len());
  	memcpy (arg.data.base (), data.cstr(), data.len());
	}
	
  gwclnt->call (DHASHPROC_RETRIEVE, &arg, res, 
		wrap (this, &dhashclient::retrievecb, cb, key, res));
}
Пример #19
0
bool
basename_dirname (const str &in, str *d, str *b)
{
  size_t l = in.len ();

  if (l == 0) {
    *d = *b = NULL;
    return false;
  }

  bool ret = (in[0] == '/');
  const char *bp = in.cstr ();
  const char *ep = bp + l - 1;
  const char *p;
  for ( p = ep; p >= bp && *p != '/'; p--) ;

  // Set the basename if possible
  if (p == ep) {
    *b = NULL;
  } else {
    *b = str (p + 1);
  }

  // if there were multiple slashes keep backing up
  for ( ; p >= bp && *p == '/' ; p-- );

  if (p >= bp) {
    assert (*p != '/');
    *d = str (bp, p - bp + 1);
  } else {
    *d = NULL;
  }
  
  return ret;
}
Пример #20
0
Файл: rxx.C Проект: aosmith/okws
bool
repl_t::parse (str in)
{
  const char *bp = in.cstr ();
  const char *ep = bp + in.len ();
  const char *last = bp;
  size_t inc = 1;

  for (const char *p = bp; p < ep; p += inc) {
    bool is_dig = false;
    inc = 1;
    
    if (p == ep - 1 || *p != '$') { /* noop */ }

    else if (p[1] == '$' || (is_dig = (isdigit (p[1])))) {

      add_str (bp, last, p, ep);
      inc = 2;

      if (is_dig) {
	add_capture (p[1] - '0');
	last = p + 2;
      } else {
	last = p + 1;
      }
    }

  }
  add_str (bp, last, ep, ep);
  return true;
}
Пример #21
0
void
json_XDR_t::error_wrong_type (str s, ptr<const pub3::expr_t> x)
{
  str got = x->type_to_str ();
  strbuf msg ("got type %s; expected %s", got.cstr (), s.cstr ());
  error_generic (msg);
}
Пример #22
0
str
html_wss (str in)
{
  if (!in) return in;
  mstr out (in.len ());
  char *op = out.cstr ();
  const char *ip = in.cstr ();
  const char *ep = ip + in.len ();
  
  bool eat_ws_state = false;
  for ( ; ip < ep; ip++) {
    if (isspace (*ip)) {
      if (!eat_ws_state) {
	eat_ws_state = true;
      }
    } else {
      if (eat_ws_state) {
	*op++ = ' ';
	eat_ws_state = false;
      }
      *op++ = *ip;
    }
  }
  if (eat_ws_state) { *op++ = ' '; }
  out.setlen (op - out.cstr ());
  return out;
}
Пример #23
0
static str
pathexpand (str lookup, str *sch, int recdepth = 0)
{
  char readlinkbuf [PATH_MAX + 1];
  str s;

  struct stat sb;
  while (1) {
//     warn << print_indent (recdepth) << "looking up " << lookup << "\n";

    stat (lookup.cstr (), &sb);
    
    errno = 0;
    if ((s = slashsfs2sch (lookup))) {
//       warn << print_indent (recdepth) << "--------FOUND-----: " 
// 	   << s << "\n";
      *sch = s;
      return lookup;
    }
    else {
      int len = readlink (lookup, readlinkbuf, PATH_MAX);
      if (len < 0) {
// 	warn << print_indent (recdepth) << "readlink of " 
// 	     << lookup << " returned error: " << strerror (errno) << "\n";
	return lookup;
      }
      readlinkbuf[len] = 0;
//       warn << print_indent (recdepth) << "readlink of " << lookup 
// 	   << " returned " << readlinkbuf << "\n";
      lookup = mk_readlinkres_abs (readlinkbuf, lookup);
    }
  }
}
Пример #24
0
str
fix_exec_path (str path, str dir)
{
  const char *prog = strrchr (path, '/');
  if (prog)
    return path;

  if (!dir)
    dir = execdir;
  path = dir << "/" << path;
  prog = strrchr (path, '/');
  if (!prog)
    panic ("No EXECDIR for unqualified path %s.\n", path.cstr ());

#ifdef MAINTAINER
  if (builddir && dir == execdir) {
    str np;
    np = builddir << prog;
    if (execok (np))
      return np;
    np = builddir << prog << prog;
    if (execok (np))
      return np;
    if (np = searchdir (builddir, prog))
      return np;
    if (np = searchdir (builddir << "/lib", prog))
      return np;
  }
#endif /* MAINTAINER */

  return path;
}
Пример #25
0
 void
 dumpable_t::s_dump (dumper_t *d, str prfx, const dumpable_t *obj)
 {
   if (prfx) { d->dump (strbuf ("%s ", prfx.cstr ()), false); }
   if (obj) { obj->dump (d); }
   else { d->dump ("(null)", true); }
 }
Пример #26
0
//
// write out the data 's' to the file given by _file.  Might need to make
// some parent directories if the filename contains slashes.
//
// return -1 if failure, and 0 if wrote the file out OK.
//
int write_file (const str &nm, const str &dat, bool do_fsync)
{   
  char *s = strdup (nm.cstr ());
  int rc = 0;

  rc = mkdir_p (s);

  if (rc == 0 && !my_str2file (nm, dat, 0666, do_fsync)) {
    warn ("cannot create file %s: %m\n", nm.cstr ());
    rc = -1;
  } else {
    rc = 0;
  }

  if (s) free (s);
  return rc;
}
Пример #27
0
 void 
 ssl_complain (const str &s)
 {
   if (s)
     BIO_printf (_bio_err, "%s", s.cstr ());
   ERR_print_errors (_bio_err);
   fflush (stderr);
 }
Пример #28
0
str
apply_container_dir (const str &d, const str &f)
{
  if (f[0] == '/' || !d)
    return re_fslash (f.cstr ());
  else 
    return (strbuf (d) << "/" << f);
}
Пример #29
0
Файл: acl.C Проект: bougyman/sfs
void
acl::fix_aclstr (str s, char *buf)
{
  char sbuf[ACLSIZE];
  int min = (ACLSIZE > s.len ()) ? s.len () : ACLSIZE;
  bzero (buf, ACLSIZE);
  bzero (sbuf, ACLSIZE);
  
  memcpy (sbuf, s.cstr (), min);

  str aclend (ENDACL "\n");
  int tail = aclend.len ();
  char *c = strstr (sbuf, ENDACL);
  int p = c ? c - sbuf : 0;

  int total = p ? p + tail : s.len () + tail;
  if (!p)
    warn << "ACLEND not found in ACL \n";
  
  if (total <= ACLSIZE) {
    memcpy (buf, s.cstr (), p);
    memcpy (buf + p, aclend.cstr (), aclend.len ());
    return;
  }

  if (total > ACLSIZE) {
    if (p)
      warn << "ACLEND found at position " << p << "\n";
    else
      warn << "ACLEND not found in ACL \n";

    warn << "ACL does not fit in buffer. Truncating \n";
    if ( p && p < (ACLSIZE - tail)) {
      warn << "Removing garbage after ACLEND \n";
      memcpy (buf, s.cstr (), p);
      memcpy (buf + p, aclend.cstr (), aclend.len ());
      return;
    }
    else {
      memcpy (buf, s.cstr (), ACLSIZE - tail);
      memcpy (buf + ACLSIZE - tail, aclend.cstr (), tail);
      return;
    }
  }
}
bool
siglog (const str &line)
{
  if (!line) return false;
  int n = write (logfd, line.cstr (), line.len ());
  if (n < int (line.len ())) 
    return false;
  return true;
}