static NEOERR *wdb_save_defn (WDB *wdb, const char *name)
{
  char path[_POSIX_PATH_MAX];
  char path2[_POSIX_PATH_MAX];
  FILE *fp;
  NEOERR *err = STATUS_OK;
  int r;

  snprintf (path, sizeof(path), "%s.wdf.new", name);
  snprintf (path2, sizeof(path2), "%s.wdf", name);
  fp = fopen (path, "w");
  if (fp == NULL)
    return nerr_raise_errno (NERR_IO, "Unable to open defn %s", name);

  err = wdb_save_defn_v1 (wdb, fp);
  fclose (fp);
  if (err != STATUS_OK) 
  {
    unlink (path);
    return nerr_pass (err);
  }

  r = unlink (path2);
  if (r == -1 && errno != ENOENT)
    return nerr_raise_errno (NERR_IO, "Unable to unlink %s", path2);
  r = link (path, path2);
  if (r == -1)
    return nerr_raise_errno (NERR_IO, "Unable to link %s to %s", path, path2);
  r = unlink (path);

  wdb->defn_dirty = 0;
  wdb->table_version = rand();

  return STATUS_OK;
}
/* Also, an annoyance here... what to do with the EOF case?  Currently,
 * we're just returing with a ol of 0, which means in most cases when
 * calling this we have to check that case as well as standard errors.
 * We could raise an NERR_EOF or something, but that seems like
 * overkill.  We should probably have a ret arg for the case... */
static NEOERR *ne_net_fill(NSOCK *sock)
{
  NEOERR *err;
  struct timeval tv;
  fd_set fds;
  int r;

  /* Ok, we are assuming a model where one side of the connection is the
   * consumer and the other the producer... and then it switches.  So we
   * flush the output buffer (if any) before we read */
  if (sock->ol)
  {
    err = ne_net_flush(sock);
    if (err) return nerr_pass(err);
  }

  /* Ok, we want connections to fail if they don't connect in
   * conn_timeout... but with higher listen queues, the connection could
   * actually connect, but the remote server won't get to it within the
   * conn_timeout, we still want it to fail.  We do that by using the
   * conn_timeout on the first read ... this isn't quite the same as we
   * might actually timeout at almost 2x conn_timeout (if we had to wait
   * for connect and the first read) but its still better then waiting
   * the full data timeout */
  if (sock->conn_timeout)
  {
    tv.tv_sec = sock->conn_timeout;
    sock->conn_timeout = 0;
  }
  else
  {
    tv.tv_sec = sock->data_timeout;
  }
  tv.tv_usec = 0;

  FD_ZERO(&fds);
  FD_SET(sock->fd, &fds);

  r = select(sock->fd+1, &fds, NULL, NULL, &tv);
  if (r == 0)
  {
    return nerr_raise(NERR_IO, "read failed: Timeout");
  }
  if (r < 0)
  {
    return nerr_raise_errno(NERR_IO, "select for read failed");
  }

  sock->ibuf[0] = '\0';
  r = read(sock->fd, sock->ibuf, NET_BUFSIZE);
  if (r < 0)
  {
    return nerr_raise_errno(NERR_IO, "read failed");
  }

  sock->ib = 0;
  sock->il = r;

  return STATUS_OK;
}
Exemple #3
0
/* The search path is part of the HDF by convention */
NEOERR* hdf_search_path (HDF *hdf, const char *path, char *full, int full_len)
{
  HDF *paths;
  struct stat s;

  for (paths = hdf_get_child (hdf, "hdf.loadpaths");
      paths;
      paths = hdf_obj_next (paths))
  {
    snprintf (full, full_len, "%s/%s", hdf_obj_value(paths), path);
    errno = 0;
    if (stat (full, &s) == -1)
    {
      if (errno != ENOENT)
	return nerr_raise_errno (NERR_SYSTEM, "Stat of %s failed", full);
    }
    else
    {
      return STATUS_OK;
    }
  }

  strncpy (full, path, full_len);
  if (stat (full, &s) == -1)
  {
    if (errno != ENOENT)
      return nerr_raise_errno (NERR_SYSTEM, "Stat of %s failed", full);
  }
  else return STATUS_OK;

  return nerr_raise (NERR_NOT_FOUND, "Path %s not found", path);
}
Exemple #4
0
NEOERR *hdf_write_file_atomic (HDF *hdf, const char *path)
{
  NEOERR *err;
  FILE *fp;
  char tpath[PATH_BUF_SIZE];
  static int count = 0;

  snprintf(tpath, sizeof(tpath), "%s.%5.5f.%d", path, ne_timef(), count++);

  fp = fopen(tpath, "w");
  if (fp == NULL)
    return nerr_raise_errno (NERR_IO, "Unable to open %s for writing", tpath);

  err = hdf_dump_format (hdf, 0, fp);

  fclose (fp);

  if (err)
  {
    unlink(tpath);
    return nerr_pass(err);
  }
  if (rename(tpath, path) == -1)
  {
    unlink (tpath);
    return nerr_raise_errno (NERR_IO, "Unable to rename file %s to %s",
	tpath, path);
  }

  return STATUS_OK;
}
Exemple #5
0
NEOERR *ne_remove_dir (const char *path)
{
  NEOERR *err;
  DIR *dp;
  struct stat s;
  struct dirent *de;
  char npath[PATH_BUF_SIZE];

  if (stat(path, &s) == -1)
  {
    if (errno == ENOENT) return STATUS_OK;
    return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", path);
  }
  if (!S_ISDIR(s.st_mode))
  {
    return nerr_raise (NERR_ASSERT, "Path %s is not a directory", path);
  }
  dp = opendir(path);
  if (dp == NULL)
    return nerr_raise_errno (NERR_IO, "Unable to open directory %s", path);
  while ((de = readdir (dp)) != NULL)
  {
    if (strcmp(de->d_name, ".") && strcmp(de->d_name, ".."))
    {
      snprintf (npath, sizeof(npath), "%s/%s", path, de->d_name);
      if (stat(npath, &s) == -1)
      {
	if (errno == ENOENT) continue;
	closedir(dp);
	return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", npath);
      }
      if (S_ISDIR(s.st_mode))
      {
	err = ne_remove_dir(npath);
	if (err) break;
      }
      else
      {
	if (unlink(npath) == -1)
	{
	  if (errno == ENOENT) continue;
	  closedir(dp);
	  return nerr_raise_errno (NERR_SYSTEM, "Unable to unlink file %s", 
	      npath);
	}
      }
    }
  }
  closedir(dp);
  if (rmdir(path) == -1)
  {
    return nerr_raise_errno (NERR_SYSTEM, "Unable to rmdir %s", path);
  }
  return STATUS_OK;
}
Exemple #6
0
NEOERR *ne_load_file_len (const char *path, char **str, int *out_len)
{
  struct stat s;
  int fd;
  int len;
  int bytes_read;

  *str = NULL;
  if (out_len) *out_len = 0;

  if (stat(path, &s) == -1)
  {
    if (errno == ENOENT)
      return nerr_raise (NERR_NOT_FOUND, "File %s not found", path);
    return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", path);
  }

  if (s.st_size >= INT_MAX)
      return nerr_raise (NERR_ASSERT, "File %s too large (%ld >= INT_MAX)",
                         path, s.st_size);

  if (s.st_size < 0)
      return nerr_raise (NERR_ASSERT, "File %s size error? (%ld < 0)", path,
                         s.st_size);

  fd = open (path, O_RDONLY);
  if (fd == -1)
  {
    return nerr_raise_errno (NERR_SYSTEM, "Unable to open file %s", path);
  }
  len = s.st_size;
  *str = (char *) malloc (len + 1);

  if (*str == NULL)
  {
    close(fd);
    return nerr_raise (NERR_NOMEM, 
	"Unable to allocate memory (%d) to load file %s", len + 1, path);
  }
  if ((bytes_read = read (fd, *str, len)) == -1)
  {
    close(fd);
    free(*str);
    return nerr_raise_errno (NERR_SYSTEM, "Unable to read file %s", path);
  }

  (*str)[bytes_read] = '\0';
  close(fd);
  if (out_len) *out_len = bytes_read;

  return STATUS_OK;
}
Exemple #7
0
NEOERR *ne_mkdirs (const char *path, mode_t mode)
{
  char mypath[PATH_BUF_SIZE];
  int x;
  int r;

  strncpy (mypath, path, sizeof(mypath));
  x = strlen(mypath);
  if (((size_t)x < sizeof(mypath)) && (mypath[x-1] != '/'))
  {
    mypath[x] = '/';
    mypath[x+1] = '\0';
  }

  for (x = 1; mypath[x]; x++)
  {
    if (mypath[x] == '/')
    {
      mypath[x] = '\0';
#ifdef __MINGW32__
      /* Braindead MINGW32 doesn't just have a dummy argument for mode */
      r = mkdir (mypath);
#else
      r = mkdir (mypath, mode);
#endif

      if (r == -1 && errno != EEXIST)
      {
	return nerr_raise_errno(NERR_SYSTEM, "ne_mkdirs: mkdir(%s, %x) failed", mypath, mode);
      }
      mypath[x] = '/';
    }
  }
  return STATUS_OK;
}
Exemple #8
0
NEOERR *fLock(int lock) 
{

  if(lockf(lock, F_LOCK, 0) < 0)
    return nerr_raise_errno (NERR_LOCK, "File lock failed");

  return STATUS_OK;
}
Exemple #9
0
NEOERR *filter_create_fp(const char *cmd, FILE **in, FILE **out, FILE **err, 
                         pid_t *pid)
{
  NEOERR *nerr;
  int fdin = 0, fdout = 0, fderr = 0;
  int *pfdin = NULL, *pfdout = NULL, *pfderr = NULL;

  if (in) pfdin = &fdin;
  if (out) pfdout = &fdout;
  if (err) pfderr = &fderr;

  nerr = filter_create_fd(cmd, pfdin, pfdout, pfderr, pid);
  if (nerr) return nerr_pass(nerr);

  if (in)
  {
    *in = fdopen (fdin, "w");
    if (*in == NULL)
      return nerr_raise_errno(NERR_IO, "Unable to fdopen in for command: %s", 
	  cmd);
  }

  if (out)
  {
    *out = fdopen (fdout, "r");
    if (*out == NULL)
    {
      if (in) fclose(*in);
      return nerr_raise_errno(NERR_IO, "Unable to fdopen out for command: %s", 
	  cmd);
    }
  }

  if (err)
  {
    *err = fdopen (fderr, "r");
    if (*err == NULL)
    {
      if (in) fclose(*in);
      if (out) fclose(*out);
      return nerr_raise_errno(NERR_IO, "Unable to fdopen err for command: %s", 
	  cmd);
    }
  }
  return STATUS_OK;
}
NEOERR *cgiwrap_write (const char *buf, int buf_len)
{
  int r;

  if (GlobalWrapper.write_cb != NULL)
  {
    r = GlobalWrapper.write_cb (GlobalWrapper.data, buf, buf_len);
    if (r != buf_len)
      return nerr_raise_errno (NERR_IO, "write_cb returned %d<%d", r, buf_len);
  }
  else
  {
    /* r = fwrite(buf, sizeof(char), buf_len, stderr);  */
    r = fwrite(buf, sizeof(char), buf_len, stdout);
    if (r != buf_len)
      return nerr_raise_errno (NERR_IO, "fwrite returned %d<%d", r, buf_len);
  }
  return STATUS_OK;
}
NEOERR *ne_net_flush(NSOCK *sock)
{
  fd_set fds;
  struct timeval tv;
  int r;
  int x = 0;

  if (sock->conn_timeout)
  {
    tv.tv_sec = sock->conn_timeout;
  }
  else
  {
    tv.tv_sec = sock->data_timeout;
  }
  tv.tv_usec = 0;

  x = 0;
  while (x < sock->ol)
  {
    FD_ZERO(&fds);
    FD_SET(sock->fd, &fds);

    r = select(sock->fd+1, NULL, &fds, NULL, &tv);
    if (r == 0)
    {
      return nerr_raise(NERR_IO, "write failed: Timeout");
    }
    if (r < 0)
    {
      return nerr_raise_errno(NERR_IO, "select for write failed");
    }

    r = write(sock->fd, sock->obuf + x, sock->ol - x);
    if (r < 0)
    {
      return nerr_raise_errno(NERR_IO, "select for write failed");
    }
    x += r;
  }
  sock->ol = 0;
  return STATUS_OK;
}
static NEOERR *wdb_load_defn (WDB *wdb, const char *name)
{
  char path[_POSIX_PATH_MAX];
  char line[1024];
  FILE *fp;
  NEOERR *err = STATUS_OK;

  snprintf (path, sizeof(path), "%s.wdf", name);
  fp = fopen (path, "r");
  if (fp == NULL)
  {
    if (errno == ENOENT)
      return nerr_raise (NERR_NOT_FOUND, "Unable to open defn %s", name);
    return nerr_raise_errno (NERR_IO, "Unable to open defn %s", name);
  }

  /* Read Version string */
  if (fgets (line, sizeof(line), fp) == NULL)
  {
    fclose(fp);
    return nerr_raise_errno (NERR_IO, "Unable to read defn %s", name);
  }
  string_rstrip(line);

  if (!strcmp(line, DEFN_VERSION_1))
  {
    err = wdb_load_defn_v1(wdb, fp);
    fclose(fp);
    if (err) return nerr_pass(err);
  }
  else
  {
    fclose(fp);
    return nerr_raise (NERR_ASSERT, "Unknown defn version %s: %s", line, name);
  }

  wdb->table_version = rand();

  return STATUS_OK;
}
Exemple #13
0
NEOERR *ne_save_file (const char *path, char *str)
{
  NEOERR *err;
  int fd;
  int w, l;

  fd = open (path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
  if (fd == -1)
  {
    return nerr_raise_errno (NERR_IO, "Unable to create file %s", path);
  }
  l = strlen(str);
  w = write (fd, str, l);
  if (w != l)
  {
    err = nerr_raise_errno (NERR_IO, "Unable to write file %s", path);
    close (fd);
    return err;
  }
  close (fd);

  return STATUS_OK;
}
NEOERR * rcfs_listdir (const char *path, ULIST **list)
{
  NEOERR *err;
  DIR *dp;
  ULIST *files;
  struct dirent *de;
  int l;
  char *f;

  *list = NULL;
  err = uListInit (&files, 10, 0);
  if (err) return nerr_pass (err);
  dp = opendir(path);
  if (dp == NULL)
  {
    uListDestroy(&files, ULIST_FREE);
    if (errno == ENOENT)
      return nerr_raise (NERR_NOT_FOUND, "Directory %s doesn't exist", path);
    return nerr_raise_errno (NERR_IO, "Unable to open directory %s", path);
  }
  while ((de = readdir (dp)) != NULL)
  {
    l = strlen (de->d_name);
    if (l>4 && !strcmp (de->d_name+l-4, ",log"))
    {
      f = (char *) malloc ((l-3) * sizeof(char));
      if (f == NULL)
      {
	uListDestroy (&files, ULIST_FREE);
	closedir(dp);
	return nerr_raise (NERR_NOMEM, 
	    "Unable to allocate memory for filename %s", de->d_name);
      }
      strncpy (f, de->d_name, l-4);
      f[l-4] = '\0';
      err = uListAppend (files, f);
      if (err)
      {
	free (f);
	uListDestroy (&files, ULIST_FREE);
	closedir(dp);
	return nerr_pass (err);
      }
    }
  }
  *list = files;
  closedir(dp);

  return STATUS_OK;
}
Exemple #15
0
NEOERR *fFind(int *plock, const char *file) 
{
  int lock;

  *plock = -1;

  if((lock = open(file, O_WRONLY|O_NDELAY|O_APPEND, 0666)) < 0) {
    if (errno == ENOENT)
      return nerr_raise (NERR_NOT_FOUND, "Unable to find lock file %s", file);
    return nerr_raise_errno (NERR_IO, "Unable to open lock file %s", file);
  }

  *plock = lock;

  return STATUS_OK;
}
Exemple #16
0
NEOERR *ne_listdir_fmatch(const char *path, ULIST **files, MATCH_FUNC fmatch, 
                          void *rock)
{
  DIR *dp;
  struct dirent *de;
  ULIST *myfiles = NULL;
  NEOERR *err = STATUS_OK;

  if (files == NULL) 
    return nerr_raise(NERR_ASSERT, "Invalid call to ne_listdir_fmatch");

  if (*files == NULL)
  {
    err = uListInit(&myfiles, 10, 0);
    if (err) return nerr_pass(err);
  }
  else
  {
    myfiles = *files;
  }

  if ((dp = opendir (path)) == NULL)
  {
    return nerr_raise_errno(NERR_IO, "Unable to opendir %s", path);
  }
  while ((de = readdir (dp)) != NULL)
  {
    if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
      continue;

    if (fmatch != NULL && !fmatch(rock, de->d_name))
      continue;

    err = uListAppend(myfiles, strdup(de->d_name));
    if (err) break;
  }
  closedir(dp);
  if (err && *files == NULL)
  {
    uListDestroy(&myfiles, ULIST_FREE);
  }
  else if (*files == NULL)
  {
    *files = myfiles;
  }
  return nerr_pass(err);
}
NEOERR *cgiwrap_writevf (const char *fmt, va_list ap) 
{
  int r;

  if (GlobalWrapper.writef_cb != NULL)
  {
    r = GlobalWrapper.writef_cb (GlobalWrapper.data, fmt, ap);
    if (r) 
      return nerr_raise_errno (NERR_IO, "writef_cb returned %d", r);
  }
  else
  {
    vprintf (fmt, ap);
    /* vfprintf(stderr, fmt, ap); */
  }
  return STATUS_OK;
}
Exemple #18
0
NEOERR *hdf_write_file (HDF *hdf, const char *path)
{
  NEOERR *err;
  FILE *fp;

  fp = fopen(path, "w");
  if (fp == NULL)
    return nerr_raise_errno (NERR_IO, "Unable to open %s for writing", path);

  err = hdf_dump_format (hdf, 0, fp);

  fclose (fp);
  if (err)
  {
    unlink(path);
  }
  return nerr_pass(err);
}
static NEOERR * _meta_save (const char *path, HDF *meta)
{
  NEOERR *err;
  char ftmp[_POSIX_PATH_MAX];
  char fpath[_POSIX_PATH_MAX];

  snprintf (ftmp, sizeof(ftmp), "%s,log.tmp", path);
  snprintf (fpath, sizeof(fpath), "%s,log", path);

  err = hdf_write_file (meta, ftmp);
  if (err) return nerr_pass (err);
  if (rename (ftmp, fpath) == -1)
  {
    unlink (ftmp);
    return nerr_raise_errno (NERR_IO, "Unable to rename file %s", ftmp);
  }

  return STATUS_OK;
}
NEOERR *ne_net_accept(NSOCK **sock, int sfd, int data_timeout)
{
  NSOCK *my_sock;
  int fd;
  struct sockaddr_in client_addr;
  socklen_t len;

  len = sizeof(struct sockaddr_in);
  while (1)
  {
    fd = accept(sfd, (struct sockaddr *)&client_addr, &len);
    if (fd >= 0) break;
    if (ShutdownAccept || errno != EINTR)
    {
      return nerr_raise_errno(NERR_IO, "accept() returned error");
    }
    if (errno == EINTR)
    {
      ne_warn("accept received EINTR");
    }
  }

  my_sock = (NSOCK *) calloc(1, sizeof(NSOCK));
  if (my_sock == NULL)
  {
    close(fd);
    return nerr_raise(NERR_NOMEM, "Unable to allocate memory for NSOCK");
  }
  my_sock->fd = fd;
  my_sock->remote_ip = ntohl(client_addr.sin_addr.s_addr);
  my_sock->remote_port = ntohs(client_addr.sin_port);
  my_sock->data_timeout = data_timeout;

  *sock = my_sock;

  return STATUS_OK;
}
Exemple #21
0
NEOERR *fCreate(int *plock, const char *file) 
{
  NEOERR *err;
  int lock;
  char *p;

  *plock = -1;

  /* note the default mode of 666 is possibly a security hole in that
   * someone else can grab your lock and DoS you.  For internal use, who
   * cares?
   */
  if((lock = open(file, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT|O_EXCL, 0666)) < 0) 
  {
    if (errno == ENOENT)
    {
      p = strrchr (file, '/');
      if (p != NULL)
      {
	*p = '\0';
	err = ne_mkdirs(file, 0777);
	*p = '/';
	if (err != STATUS_OK) return nerr_pass(err);
	lock = open(file, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0666);
      }
    }
    if (errno == EEXIST)
      return nerr_pass(fFind(plock, file));

    if (lock < 0)
      return nerr_raise_errno (NERR_IO, "Unable to open lock file %s", file);
  }

  *plock = lock;

  return STATUS_OK;
}
Exemple #22
0
NEOERR *filter_create_fd (const char *cmd, int *fdin, int *fdout, int *fderr, 
                          pid_t *pid)
{
  int pi[2]={-1,-1}, po[2]={-1,-1}, pe[2]={-1,-1};
  int rpid;

  *pid = 0;

  if (fdin)
  {
    *fdin = 0;
    if (pipe (pi) == -1)
      return nerr_raise_errno(NERR_SYSTEM, 
                              "Unable to open in pipe for command: %s", cmd);
  }

  if (fdout)
  {
    *fdout = 0;
    if (pipe (po) == -1)
    {
      if (fdin)
      {
	close (pi[0]);
	close (pi[1]);
      }
      return nerr_raise_errno(NERR_SYSTEM, 
                              "Unable to open out pipe for command: %s", cmd);
    }
  }

  if (fderr)
  {
    *fderr = 0;
    if (pipe (pe) == -1)
    {
      if (fdin)
      {
	close (pi[0]);
	close (pi[1]);
      }
      if (fdout)
      {
	close (po[0]);
	close (po[1]);
      }
      return nerr_raise_errno(NERR_SYSTEM, "Unable to open err pipe for command: %s", cmd);
    }
  }

  /* block signals */

  if ((rpid = fork ()) == 0)
  {
    /* unblock signals */

    if (fdin)
    {
      close (pi[1]);
      dup2 (pi[0], 0);
      close (pi[0]);
    }

    if (fdout)
    {
      close (po[0]);
      dup2 (po[1], 1);
      close (po[1]);
    }

    if (fderr)
    {
      close (pe[0]);
      dup2 (pe[1], 2);
      close (pe[1]);
    }

    execl ("/bin/sh", "sh", "-c", cmd, (void *)NULL);
    _exit (127);
  }
  else if (rpid == -1)
  {
    /* unblock signals */
    if (fdin)
    {
      close (pi[0]);
      close (pi[1]);
    }
    if (fdout)
    {
      close (po[0]);
      close (po[1]);
    }
    if (fderr)
    {
      close (pe[0]);
      close (pe[1]);
    }
    return nerr_raise_errno(NERR_SYSTEM, "Unable to fork for command: %s", cmd);
  }

  if (fdout)
  {
    close (po[1]);
    *fdout = po[0];
  }
  if (fdin)
  {
    close (pi[0]);
    *fdin = pi[1];
  }
  if (fderr)
  {
    close (pe[1]);
    *fderr = pe[0];
  }
  *pid = rpid;

  return STATUS_OK;
}
/* Client side */
NEOERR *ne_net_connect(NSOCK **sock, const char *host, int port, 
                       int conn_timeout, int data_timeout)
{
  struct sockaddr_in serv_addr;
  struct hostent hp;
  struct hostent *php;
  int fd;
  int r = 0, x;
  int flags;
  struct timeval tv;
  fd_set fds;
  int optval;
  socklen_t optlen;
  NSOCK *my_sock;

  /* FIXME: This isn't thread safe... but there's no man entry for the _r
   * version? */

  php = gethostbyname(host);
  if (php == NULL)
  {
    return nerr_raise(NERR_IO, "Host not found: %s", hstrerror(h_errno));
  }
  hp = *php;

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_port = htons(port);
  fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (fd == -1)
    return nerr_raise_errno(NERR_IO, "Unable to create socket");

  flags = fcntl(fd, F_GETFL, 0 );
  if (flags == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to get socket flags");
  }

  if (fcntl(fd, F_SETFL, flags | O_NDELAY) == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to set O_NDELAY");
  }

  x = 0;
  while (hp.h_addr_list[x] != NULL)
  {
    memcpy(&(serv_addr.sin_addr), hp.h_addr_list[x], sizeof(struct in_addr));
    errno = 0;
    r = connect(fd, (struct sockaddr *) &(serv_addr), sizeof(struct sockaddr_in));
    if (r == 0 || errno == EINPROGRESS) break;
    x++;
  }
  if (r != 0)
  {
    if (errno != EINPROGRESS)
    {
      close(fd);
      return nerr_raise_errno(NERR_IO, "Unable to connect to %s:%d", 
	  host, port);
    }
    tv.tv_sec = conn_timeout;
    tv.tv_usec = 0;

    FD_ZERO(&fds);
    FD_SET(fd, &fds);

    r = select(fd+1, NULL, &fds, NULL, &tv);
    if (r == 0)
    {
      close(fd);
      return nerr_raise(NERR_IO, "Connection to %s:%d failed: Timeout", host,
	  port);
    }
    if (r < 0)
    {
      close(fd);
      return nerr_raise_errno(NERR_IO, "Connection to %s:%d failed", host,
	  port);
    }

    optlen = sizeof(optval);

    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) 
    {
      close(fd);
      return nerr_raise_errno(NERR_IO, 
	  "Unable to getsockopt to determine connection error");
    }

    if (optval)
    {
      close(fd);
      errno = optval;
      return nerr_raise_errno(NERR_IO, "Connection to %s:%d failed", host, 
	  port);
    }
  }
  /* Re-enable blocking... we'll use select on read/write for timeouts
   * anyways, and if we want non-blocking version in the future we'll
   * add a flag or something.
   */
  flags = fcntl(fd, F_GETFL, 0 );
  if (flags == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to get socket flags");
  }

  if (fcntl(fd, F_SETFL, flags & ~O_NDELAY) == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to set O_NDELAY");
  }

  my_sock = (NSOCK *) calloc(1, sizeof(NSOCK));
  if (my_sock == NULL)
  {
    close(fd);
    return nerr_raise(NERR_NOMEM, "Unable to allocate memory for NSOCK");
  }
  my_sock->fd = fd;
  my_sock->remote_ip = ntohl(serv_addr.sin_addr.s_addr);
  my_sock->remote_port = port;
  my_sock->data_timeout = data_timeout;
  my_sock->conn_timeout = conn_timeout;

  *sock = my_sock;

  return STATUS_OK;
}
Exemple #24
0
NEOERR *ne_remove_dir (const char *path)
{
#ifdef _MSC_VER
  SHFILEOPSTRUCT op;
  op.hwnd = NULL;
  op.wFunc = FO_DELETE;
  char* tmp = (char*)calloc(1, strlen(path) + 2);
  memcpy(tmp, path, strlen(path));
  op.pFrom = tmp;
  op.pTo = NULL;
  op.fFlags = FOF_SILENT;
  op.hNameMappings = NULL;
  op.lpszProgressTitle = NULL;

  int res = SHFileOperation(&op);
  free(tmp);
  if (res != 0)
    return nerr_raise_errno(NERR_SYSTEM, "Unable to stat file %s", path);
#else
  NEOERR *err;
  DIR *dp;
  struct stat s;
  struct dirent *de;
  char npath[PATH_BUF_SIZE];

  if (stat(path, &s) == -1)
  {
    if (errno == ENOENT) return STATUS_OK;
    return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", path);
  }
  if (!S_ISDIR(s.st_mode))
  {
    return nerr_raise (NERR_ASSERT, "Path %s is not a directory", path);
  }
  dp = opendir(path);
  if (dp == NULL)
    return nerr_raise_errno (NERR_IO, "Unable to open directory %s", path);
  while ((de = readdir (dp)) != NULL)
  {
    if (strcmp(de->d_name, ".") && strcmp(de->d_name, ".."))
    {
      snprintf (npath, sizeof(npath), "%s/%s", path, de->d_name);
      if (stat(npath, &s) == -1)
      {
	if (errno == ENOENT) continue;
	closedir(dp);
	return nerr_raise_errno (NERR_SYSTEM, "Unable to stat file %s", npath);
      }
      if (S_ISDIR(s.st_mode))
      {
	err = ne_remove_dir(npath);
	if (err) break;
      }
      else
      {
	if (unlink(npath) == -1)
	{
	  if (errno == ENOENT) continue;
	  closedir(dp);
	  return nerr_raise_errno (NERR_SYSTEM, "Unable to unlink file %s",
	      npath);
	}
      }
    }
  }
  closedir(dp);
  if (rmdir(path) == -1)
  {
    return nerr_raise_errno (NERR_SYSTEM, "Unable to rmdir %s", path);
  }
#endif
  return STATUS_OK;
}
Exemple #25
0
NEOERR *ne_listdir_fmatch(const char *path, ULIST **files, MATCH_FUNC fmatch,
                          void *rock)
{
  NEOERR *err = STATUS_OK;
  ULIST *myfiles = NULL;

  if (files == NULL)
    return nerr_raise(NERR_ASSERT, "Invalid call to ne_listdir_fmatch");

  if (*files == NULL)
  {
    err = uListInit(&myfiles, 10, 0);
    if (err) return nerr_pass(err);
  }
  else
  {
    myfiles = *files;
  }

#ifdef _MSC_VER
  HANDLE hFind = INVALID_HANDLE_VALUE;
  WIN32_FIND_DATA ffd;
  CHAR rootDir[MAX_PATH];

  StringCchCopy(rootDir, MAX_PATH, path);
  StringCchCat(rootDir, MAX_PATH, TEXT("\\*"));
  hFind = FindFirstFile(rootDir, &ffd);
  if (hFind == INVALID_HANDLE_VALUE)
    return nerr_raise_errno(NERR_IO, "Unable to opendir %s", path);

  do {
    if (!strcmp(ffd.cFileName, ".") || !strcmp(ffd.cFileName, ".."))
      continue;

    if (fmatch != NULL && !fmatch(rock, ffd.cFileName))
      continue;

    err = uListAppend(myfiles, strdup(ffd.cFileName));
    if (err) break;
  } while (FindNextFile(hFind, &ffd) != 0);

  FindClose(hFind);
#else
  DIR *dp;
  struct dirent *de;
  if ((dp = opendir (path)) == NULL)
  {
    return nerr_raise_errno(NERR_IO, "Unable to opendir %s", path);
  }
  while ((de = readdir (dp)) != NULL)
  {
    if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
      continue;

    if (fmatch != NULL && !fmatch(rock, de->d_name))
      continue;

    err = uListAppend(myfiles, strdup(de->d_name));
    if (err) break;
  }
  closedir(dp);
#endif
  if (err && *files == NULL)
  {
    uListDestroy(&myfiles, ULIST_FREE);
  }
  else if (*files == NULL)
  {
    *files = myfiles;
  }
  return nerr_pass(err);
}
/* Server side */
NEOERR *ne_net_listen(int port, int *fd)
{
  int sfd = 0;
  int on = 1;
/*  int flags; */
  struct sockaddr_in serv_addr;

  if ((sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    return nerr_raise_errno(NERR_IO, "Unable to create socket");

  if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on,
	sizeof(on)) == -1)
  {
    close(sfd);
    return nerr_raise_errno(NERR_IO, "Unable to setsockopt(SO_REUSEADDR)");
  }
   
  if(setsockopt (sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
	sizeof(on)) == -1) 
  {
    close(sfd);
    return nerr_raise_errno(NERR_IO, "Unable to setsockopt(SO_KEEPALIVE)");
  }
   
  if(setsockopt (sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&on, 
	sizeof(on)) == -1)
  {
    close(sfd);
    return nerr_raise_errno(NERR_IO, "Unable to setsockopt(TCP_NODELAY)");
  }
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  serv_addr.sin_port = htons(port);

  if (bind(sfd,(struct sockaddr *)&(serv_addr),sizeof(struct sockaddr)) == -1)
  {
    close(sfd);
    return nerr_raise_errno(NERR_IO, "Unable to bind to port %d", port);
  }

  /* If set non-block, then we have to use select prior to accept...
   * typically we don't, so we'll leave this out until we have a need
   * for it and then figure out how to work it into the common code */
  /*
  flags = fcntl(sfd, F_GETFL, 0 );
  if (flags == -1)
  {
    close(sfd);
    return nerr_raise_errno(NERR_IO, "Unable to get socket flags for port %d", 
	port);
  }

  if (fcntl(sfd, F_SETFL, flags | O_NDELAY) == -1)
  {
    close(sfd);
    return nerr_raise_errno(NERR_IO, "Unable to set O_NDELAY for port %d", 
	port);
  }
  */

  if (listen(sfd, 100) == -1)
  {
    close(sfd);
    return nerr_raise_errno(NERR_IO, "Unable to listen on port %d", port);
  }
  *fd = sfd;

  return STATUS_OK;
}
NEOERR * rcfs_save (const char *path, const char *data, const char *user, 
                    const char *log)
{
  NEOERR *err;
  HDF *meta = NULL, *vers;
  char fpath[_POSIX_PATH_MAX];
  char buf[256];
  int version = 0;
  int fd;
  int lock;
  int x, l, w;

  err = rcfs_lock (path, &lock);
  if (err) return nerr_pass (err);
  do
  {
    err = rcfs_meta_load (path, &meta);
    if (err && nerr_handle (&err, NERR_NOT_FOUND))
    {
      /* new file! */
      err = hdf_init (&meta);
    }
    if (err) return nerr_pass (err);
    for (vers = hdf_get_child (meta, "Versions");
	vers;
	vers = hdf_obj_next (vers))
    {
      x = atoi (hdf_obj_name (vers));
      if (x > version) version = x;
    }

    /* new version */
    version++;
    snprintf (fpath, sizeof (fpath), "%s,%d", path, version);
    fd = open (fpath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    if (fd == -1)
    {
      err = nerr_raise_errno (NERR_IO, "Unable to create file %s", fpath);
      break;
    }
    l = strlen(data);
    w = write (fd, data, l);
    if (w != l)
    {
      err = nerr_raise_errno (NERR_IO, "Unable to write file %s", fpath);
      close (fd);
      break;
    }
    close (fd);
    snprintf (buf, sizeof(buf), "Versions.%d.Log", version);
    err = hdf_set_value (meta, buf, log);
    if (err) break;
    snprintf (buf, sizeof(buf), "Versions.%d.User", version);
    err = hdf_set_value (meta, buf, user);
    if (err) break;
    snprintf (buf, sizeof(buf), "Versions.%d.Date", version);
    err = hdf_set_int_value (meta, buf, ne_timef());
    if (err) break;
    err = _meta_save (path, meta);
  } while (0);

  rcfs_unlock (lock);
  hdf_destroy (&meta);
  return nerr_pass (err);
}