Exemplo n.º 1
0
int csync_create(CSYNC **csync, const char *local, const char *remote) {
  CSYNC *ctx;
  size_t len = 0;

  ctx = c_malloc(sizeof(CSYNC));
  if (ctx == NULL) {
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  /* remove trailing slashes */
  len = strlen(local);
  while(len > 0 && local[len - 1] == '/') --len;

  ctx->local.uri = c_strndup(local, len);

  /* remove trailing slashes */
  len = strlen(remote);
  while(len > 0 && remote[len - 1] == '/') --len;

  ctx->remote.uri = c_strndup(remote, len);

  ctx->status_code = CSYNC_STATUS_OK;

  ctx->current_fs = NULL;

  ctx->abort = false;

  *csync = ctx;
  return 0;
}
Exemplo n.º 2
0
END_TEST

START_TEST (check_c_strndup_nomem)
{
  const char *str = "test";
  char *tdup = NULL;

  tdup = c_strndup(str, 3);
  fail_unless(tdup == NULL, NULL);
}
Exemplo n.º 3
0
static void check_c_strndup(void **state)
{
  const char *str = "test";
  char *tdup = NULL;

  (void) state; /* unused */

  tdup = c_strndup(str, 3);
  assert_memory_equal(tdup, "tes", 3);

  free(tdup);
}
Exemplo n.º 4
0
END_TEST

START_TEST (check_c_strndup)
{
  const char *str = "test";
  char *tdup = NULL;

  tdup = c_strndup(str, 3);
  fail_unless(strncmp(tdup, "tes", 3) == 0, NULL);

  free(tdup);
}
Exemplo n.º 5
0
char *
c_strdup(const char *s)
{
  char *ret;
  if (!s)
    {
      ret = stp_malloc(1);
      ret[0] = 0;
      return ret;
    }
  else
    return c_strndup(s, c_strlen(s));
}
Exemplo n.º 6
0
static csync_vio_file_stat_t *_readdir(csync_vio_method_handle_t *dhandle) {
  struct smbc_dirent *dirent = NULL;
  smb_dhandle_t *handle = NULL;
  csync_vio_file_stat_t *file_stat = NULL;

  handle = (smb_dhandle_t *) dhandle;

  errno = 0;
  dirent = smbc_readdir(handle->dh);
  if (dirent == NULL) {
    return NULL;
  }

  file_stat = c_malloc(sizeof(csync_vio_file_stat_t));
  if (file_stat == NULL) {
    return NULL;
  }

  file_stat->name = c_strndup(dirent->name, dirent->namelen);
  file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;

  switch (dirent->smbc_type) {
    case SMBC_FILE_SHARE:
      file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
      file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
      break;
    case SMBC_WORKGROUP:
    case SMBC_SERVER:
    case SMBC_COMMS_SHARE:
    case SMBC_IPC_SHARE:
      break;
    case SMBC_DIR:
    case SMBC_FILE:
      file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
      if (dirent->smbc_type == SMBC_DIR) {
        file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
      } else {
        file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
      }
      break;
    default:
      break;
  }

  return file_stat;
}
Exemplo n.º 7
0
struct c_ptr_vector *
http_list_parse(const char *string) {
    struct c_ptr_vector *entries;
    const char *ptr, *start;

    entries = c_ptr_vector_new();

    ptr = string;

    start = NULL;
    for (;;) {
        if (*ptr == '\0' || *ptr == ',' || *ptr == ' ' || *ptr == '\t') {
            if (start) {
                char *token;

                token = c_strndup(start, (size_t)(ptr - start));
                c_ptr_vector_append(entries, token);

                start = NULL;
            }

            if (*ptr == '\0')
                break;
        } else {
            if (!start)
                start = ptr;
        }

        ptr++;
    }

    if (c_ptr_vector_length(entries) == 0) {
        c_ptr_vector_delete(entries);

        c_set_error("empty list");
        return NULL;
    }

    return entries;
}
Exemplo n.º 8
0
Arquivo: sircc.c Projeto: galdor/sircc
void
sircc_chan_add_user(struct sircc_chan *chan, const char *user, size_t sz) {
    if (sz == (size_t)-1)
        sz = strlen(user);

    for (size_t i = 0; i < chan->nb_users; i++) {
        if (memcmp(chan->users[i], user, sz) == 0)
            return;
    }

    if (!chan->users) {
        chan->nb_users = 0;
        chan->users = c_malloc(sizeof(char *));
    } else {
        chan->users = c_realloc(chan->users,
                                    (chan->nb_users + 1) * sizeof(char *));
    }

    chan->users[chan->nb_users] = c_strndup(user, sz);
    chan->nb_users++;

    chan->users_sorted = false;
}
Exemplo n.º 9
0
int csync_create(CSYNC **csync, const char *local, const char *remote) {
  CSYNC *ctx;
  size_t len = 0;
  char *home;
  int rc;

  ctx = c_malloc(sizeof(CSYNC));
  if (ctx == NULL) {
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  /* remove trailing slashes */
  len = strlen(local);
  while(len > 0 && local[len - 1] == '/') --len;

  ctx->local.uri = c_strndup(local, len);
  if (ctx->local.uri == NULL) {
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    free(ctx);
    return -1;
  }

  /* remove trailing slashes */
  len = strlen(remote);
  while(len > 0 && remote[len - 1] == '/') --len;

  ctx->remote.uri = c_strndup(remote, len);
  if (ctx->remote.uri == NULL) {
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    free(ctx);
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;
  ctx->options.local_only_mode = false;

  ctx->pwd.uid = getuid();
  ctx->pwd.euid = geteuid();

  home = csync_get_user_home_dir();
  if (home == NULL) {
    SAFE_FREE(ctx->local.uri);
    SAFE_FREE(ctx->remote.uri);
    SAFE_FREE(ctx);
    errno = ENOMEM;
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    return -1;
  }

  rc = asprintf(&ctx->options.config_dir, "%s/%s", home, CSYNC_CONF_DIR);
  SAFE_FREE(home);
  if (rc < 0) {
    SAFE_FREE(ctx->local.uri);
    SAFE_FREE(ctx->remote.uri);
    SAFE_FREE(ctx);
    errno = ENOMEM;
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    return -1;
  }

  ctx->local.list     = 0;
  ctx->remote.list    = 0;
  ctx->current_fs = NULL;

  ctx->abort = false;

  *csync = ctx;
  return 0;
}
Exemplo n.º 10
0
int
http_response_parse(const char *data, size_t sz, uint32_t flags,
                    struct http_response **presponse, size_t *psz) {
    struct http_response *response;
    const char *ptr;
    size_t len, toklen;
    char status_string[4];
    size_t status_sz;
    int32_t status_value;
    int ret;

    ptr = data;
    len = sz;

#define HTTP_FAIL(fmt_, ...)                  \
    do {                                      \
        if (fmt_)                             \
            c_set_error(fmt_, ##__VA_ARGS__); \
        http_response_delete(response);       \
        return -1;                            \
    } while (0)

#define HTTP_TRUNCATED()                      \
    do {                                      \
        http_response_delete(response);       \
        return 0;                             \
    } while (0)

    response = http_response_new();

    /* Version */
    toklen = c_memcspn(ptr, len, " ");
    if (toklen == len) {
        if (len > HTTP_VERSION_MAX_LENGTH)
            HTTP_FAIL("invalid version");
        HTTP_TRUNCATED();
    }

    if (http_version_parse(ptr, toklen, &response->version) == -1)
        HTTP_FAIL(NULL);

    ptr += toklen + 1;
    len -= toklen + 1;

    /* Status */
    toklen = c_memcspn(ptr, len, " ");
    if (toklen == len) {
        if (len > 3)
            HTTP_FAIL("invalid status code");
        HTTP_TRUNCATED();
    }

    if (toklen > 3)
        HTTP_FAIL("invalid status code");

    memcpy(status_string, ptr, toklen);
    status_string[toklen] = '\0';

    if (c_parse_i32(status_string, &status_value, &status_sz) == -1)
        HTTP_FAIL("invalid status code");
    if (status_sz != toklen)
        HTTP_FAIL("invalid trailing data after status code");
    response->status = (enum http_status)status_value;

    ptr += toklen + 1;
    len -= toklen + 1;

    /* Reason */
    toklen = c_memcspn(ptr, len, "\r");
    if (toklen == len) {
        if (len > HTTP_REASON_MAX_LENGTH)
            HTTP_FAIL("reason string too long");
        HTTP_TRUNCATED();
    }

    response->reason = c_strndup(ptr, toklen);

    ptr += toklen;
    len -= toklen;

    /* End of status line */
    if (len < 2)
        HTTP_TRUNCATED();
    if (ptr[0] != '\r' || ptr[1] != '\n')
        HTTP_FAIL("malformed status line");

    ptr += 2;
    len -= 2;

    /* Headers */
    http_headers_delete(response->headers);
    response->headers = NULL;

    ret = http_headers_parse(ptr, len, &response->headers, NULL, &toklen);
    if (ret == -1)
        HTTP_FAIL(NULL);
    if (ret == 0)
        HTTP_TRUNCATED();

    ptr += toklen;
    len -= toklen;

    if (http_response_preprocess_headers(response) == -1) {
        http_response_delete(response);
        return -1;
    }

    /* Body */
    if (!http_response_can_have_body(response))
        goto end;

    if (response->has_content_length) {
        if (response->content_length > HTTP_RESPONSE_MAX_CONTENT_LENGTH)
            HTTP_FAIL("payload too large");

        if (len < response->content_length)
            HTTP_TRUNCATED();

        response->body_sz = response->content_length;
        response->body = c_strndup(ptr, response->content_length);

        ptr += response->body_sz;
        len -= response->body_sz;
    } else if (response->is_body_chunked) {
        struct http_headers *trailer;
        size_t chunked_data_sz;

        ret = http_chunked_data_parse(ptr, len,
                                      &response->body, &response->body_sz,
                                      &chunked_data_sz);
        if (ret == -1)
            HTTP_FAIL("invalid chunked body: %s", c_get_error());
        if (ret == 0)
            HTTP_TRUNCATED();

        ptr += chunked_data_sz;
        len -= chunked_data_sz;

        /* Trailer */
        ret = http_headers_parse(ptr, len, &trailer, NULL, &toklen);
        if (ret == -1)
            HTTP_FAIL(NULL);
        if (ret == 0)
            HTTP_TRUNCATED();

        http_headers_merge_nocopy(response->headers, trailer);
        http_headers_delete(trailer);

        ptr += toklen;
        len -= toklen;
    } else if (response->has_connection_close) {
        size_t content_length;

        if (flags & HTTP_RESPONSE_PARSE_EOF) {
            content_length = len;

            if (content_length > HTTP_RESPONSE_MAX_CONTENT_LENGTH)
                HTTP_FAIL("payload too large");

            response->body_sz = content_length;
            response->body = c_strndup(ptr, content_length);

            ptr += response->body_sz;
            len -= response->body_sz;
        } else {
            HTTP_TRUNCATED();
        }
    } else {
        HTTP_FAIL("missing content length");
    }

#undef HTTP_FAIL
#undef HTTP_TRUNCATED

end:
    *presponse = response;
    *psz = sz - len;
    return 1;
}
Exemplo n.º 11
0
int c_parse_uri(const char *uri,
    char **scheme,
    char **user, char **passwd,
    char **host, unsigned int *port,
    char **path) {
  const char *p, *z;

  if (uri == NULL || *uri == '\0') {
    return -1;
  }

  /*
   * uri = scheme://user:password@host:port/path
   * p   = ^
   * z   = ^
   */
  p = z = uri;

  /* check for valid scheme; git+ssh, pop3 */
  while (isalpha((int) *p) || isdigit((int) *p) ||
      *p == '+' || *p == '-') {
    /*
     * uri = scheme://user:password@host:port/path
     * p   =       ^
     * z   = ^
     */
    p++;
  }

  /* get scheme */
  if (*p == ':') {
    if (scheme != NULL) {
      *scheme = c_strndup(z, p - z);

      if (*scheme == NULL) {
        errno = ENOMEM;
        return -1;
      }
    }
    p++;
    z = p;
  }

  /*
   * uri = scheme://user:password@host:port/path
   * p =          ^
   * z =          ^
   */
  p = z;

  /* do we have a hostname */
  if (p[0] == '/' && p[1] == '/') {
    /*
     * uri = scheme://user:password@host:port/path
     * p   =          ^
     * z   =          ^
     */
    z += 2;
    p = z;

    /* check for user and passwd */
    while (*p && *p != '@' && *p != '/') {
      /*
       * uri = scheme://user:password@host:port/path
       * p   =                       ^    or   ^
       * z   =          ^
       */
      p++;
    }

    /* check for user and password */
    if (*p == '@') {
      const char *q;

      q = p;

      /* check if we have a password */
      while (q > z && *q != ':') {
        /*
         * uri = scheme://user:password@host:port/path
         * p   =                       ^
         * z   =          ^
         * q   =              ^
         */
        q--;
      }

      /* password found */
      if (*q == ':') {
        if (user != NULL) {
          *user = c_strndup(z, q - z);
          if (*user == NULL) {
            errno = ENOMEM;
            if (scheme != NULL) SAFE_FREE(*scheme);
            return -1;
          }
        }

        if (passwd != NULL) {
          *passwd = c_strndup(q + 1, p - (q + 1));
          if (*passwd == NULL) {
            if (scheme != NULL) SAFE_FREE(*scheme);
            if (user   != NULL) SAFE_FREE(*user);
            errno = ENOMEM;
            return -1;
          }
        }
      } else {
        /* user only */
        if (user != NULL) {
          *user = c_strndup(z, p - z);
          if( *user == NULL) {
            if (scheme != NULL) SAFE_FREE(*scheme);
            errno = ENOMEM;
            return -1;
          }
        }
      }

      p++;
      z = p;
    }

    /*
     * uri = scheme://user:password@host:port/path
     * p =                          ^
     * z =                          ^
     */
    p = z;

    /* check for IPv6 address */
    if (*p == '[') {
      /*
       * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
       * p   =                         ^
       * z   =                        ^
       */
      p++;

      /* check if we have a valid IPv6 address */
      while (*p && (isxdigit((int) *p) || *p == '.' || *p == ':')) {
        /*
         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
         * p   =                                                                ^
         * z   =                        ^
         */
        p++;
      }

      /* valid IPv6 address found */
      if (*p == ']') {
        /*
         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
         * p   =                                                                ^
         * z   =                         ^
         */
        z++;

        if (host != NULL) {
          *host = c_strndup(z, p - z);
          if (*host == NULL) {
            if (scheme != NULL) SAFE_FREE(*scheme);
            if (user   != NULL) SAFE_FREE(*user);
            if (passwd != NULL) SAFE_FREE(*passwd);
            errno = ENOMEM;
            return -1;
          }
        }

        /*
         * uri = scheme://user:password@[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]:port/path
         * p   =                                                                 ^
         * z   =                         ^
         */
        p++;
      } else {
        /* invalid IPv6 address, assume a hostname */
        p = z;

        while (*p && *p != ':' && *p != '/') {
          p++;
          /*
           * uri = scheme://user:password@host:port/path
           * p   =                            ^ or ^
           * z   =                        ^
           */
        }

        if (host != NULL) {
          *host = c_strndup(z, p - z);
          if (*host == NULL) {
            if (scheme != NULL) SAFE_FREE(*scheme);
            if (user   != NULL) SAFE_FREE(*user);
            if (passwd != NULL) SAFE_FREE(*passwd);
            errno = ENOMEM;
            return -1;
          }
        }
      }
    } else {
      /* check for hostname */
      while (*p && *p != ':' && *p != '/') {
        /*
         * uri = scheme://user:password@host:port/path
         * p   =                            ^    ^
         * z   =                        ^
         */
        p++;
      }

      if (host != NULL) {
        *host = c_strndup(z, p - z);
        if (*host == NULL) {
          if (scheme != NULL) SAFE_FREE(*scheme);
          if (user   != NULL) SAFE_FREE(*user);
          if (passwd != NULL) SAFE_FREE(*passwd);
          errno = ENOMEM;
          return -1;
        }
      }
    }

    /* check for port */
    if (*p == ':') {
      char **e = NULL;
      /*
       * uri = scheme://user:password@host:port/path
       * p =                               ^
       * z =                               ^
       */
      z = ++p;

      /* get only the digits */
      while (isdigit((int) *p)) {
        /*
         * uri = scheme://user:password@host:port/path
         * p   =                                 ^
         * z   =                             ^
         */
        e = (char **) &p;
        p++;
      }

      if (port != NULL) {
        *port = strtoul(z, e, 0);
      }

      /*
       * uri   = scheme://user:password@host:port/path
       * p =                                     ^
       */
    }
  }

  if (*p == '\0') {
    return 0;
  }

  /* get the path with the leading slash */
  if (*p == '/') {
    if (path != NULL) {
      *path = c_strdup(p);
      if (*path == NULL) {
        if (scheme != NULL) SAFE_FREE(*scheme);
        if (user   != NULL) SAFE_FREE(*user);
        if (passwd != NULL) SAFE_FREE(*passwd);
        if (host   != NULL) SAFE_FREE(*host);
        errno = ENOMEM;
        return -1;
      }
    }

    return 0;
  }

  return -1;
}
Exemplo n.º 12
0
int csync_create(CSYNC **csync, const char *local, const char *remote) {
  CSYNC *ctx;
  size_t len = 0;
  char *home;
  int rc;

  ctx = c_malloc(sizeof(CSYNC));
  if (ctx == NULL) {
    return -1;
  }

  ctx->error_code = CSYNC_ERR_NONE;

  /* remove trailing slashes */
  len = strlen(local);
  while(len > 0 && local[len - 1] == '/') --len;

  ctx->local.uri = c_strndup(local, len);
  if (ctx->local.uri == NULL) {
    ctx->error_code = CSYNC_ERR_MEM;
    return -1;
  }

  /* remove trailing slashes */
  len = strlen(remote);
  while(len > 0 && remote[len - 1] == '/') --len;

  ctx->remote.uri = c_strndup(remote, len);
  if (ctx->remote.uri == NULL) {
    SAFE_FREE(ctx->remote.uri);
    ctx->error_code = CSYNC_ERR_MEM;
    return -1;
  }

  ctx->options.max_depth = MAX_DEPTH;
  ctx->options.max_time_difference = MAX_TIME_DIFFERENCE;
  ctx->options.unix_extensions = 0;
  ctx->options.with_conflict_copys=false;
  ctx->options.local_only_mode = false;

  ctx->pwd.uid = getuid();
  ctx->pwd.euid = geteuid();

  home = csync_get_user_home_dir();
  if (home == NULL) {
    SAFE_FREE(ctx->local.uri);
    SAFE_FREE(ctx->remote.uri);
    SAFE_FREE(ctx);
    errno = ENOMEM;
    ctx->error_code = CSYNC_ERR_MEM;
    return -1;
  }

  rc = asprintf(&ctx->options.config_dir, "%s/%s", home, CSYNC_CONF_DIR);
  SAFE_FREE(home);
  if (rc < 0) {
    SAFE_FREE(ctx->local.uri);
    SAFE_FREE(ctx->remote.uri);
    SAFE_FREE(ctx);
    errno = ENOMEM;
    ctx->error_code = CSYNC_ERR_MEM;
    return -1;
  }

  *csync = ctx;
  return 0;
}
Exemplo n.º 13
0
int csync_init(CSYNC *ctx) {
  int rc;
  time_t timediff = -1;
  char *log = NULL;
  char *exclude = NULL;
  char *lock = NULL;
  char *config = NULL;
#ifndef _WIN32
  char errbuf[256] = {0};
#endif
  
  if (ctx == NULL) {
    errno = EBADF;
    return -1;
  }
  ctx->error_code = CSYNC_ERR_NONE;

  /* Do not initialize twice */
  if (ctx->status & CSYNC_STATUS_INIT) {
    return 1;
  }

  /* load log file */
  if (csync_log_init() < 0) {
    ctx->error_code = CSYNC_ERR_LOG;
    fprintf(stderr, "csync_init: logger init failed\n");
    return -1;
  }

  /* create dir if it doesn't exist */
  if (! c_isdir(ctx->options.config_dir)) {
    c_mkdirs(ctx->options.config_dir, 0700);
  }

  if (asprintf(&log, "%s/%s", ctx->options.config_dir, CSYNC_LOG_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

  /* load log if it exists */
  if (c_isfile(log)) {
    csync_log_load(log);
  } else {
#ifndef _WIN32
    if (c_copy(SYSCONFDIR "/csync/" CSYNC_LOG_FILE, log, 0644) == 0) {
      csync_log_load(log);
    }
#endif
  }

  /* create lock file */
  if (asprintf(&lock, "%s/%s", ctx->options.config_dir, CSYNC_LOCK_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

#ifndef _WIN32
  if (csync_lock(lock) < 0) {
    ctx->error_code = CSYNC_ERR_LOCK;
    rc = -1;
    goto out;
  }
#endif

  /* load config file */
  if (asprintf(&config, "%s/%s", ctx->options.config_dir, CSYNC_CONF_FILE) < 0) {
    rc = -1;
    goto out;
  }

  if (csync_config_load(ctx, config) < 0) {
      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Could not load config file %s, using defaults.", config);
  }

#ifndef _WIN32
  /* load global exclude list */
  if (asprintf(&exclude, "%s/csync/%s", SYSCONFDIR, CSYNC_EXCLUDE_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Could not load %s - %s", exclude,
              errbuf);
  }
  SAFE_FREE(exclude);

  /* load exclude list */
  if (asprintf(&exclude, "%s/%s", ctx->options.config_dir, CSYNC_EXCLUDE_FILE) < 0) {
    ctx->error_code = CSYNC_ERR_UNSPEC;
    rc = -1;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Could not load %s - %s", exclude, 
              errbuf);
  }
#endif

  /* create/load statedb */
  if (! csync_is_statedb_disabled(ctx)) {
    uint64_t h = csync_create_statedb_hash(ctx);
    if (asprintf(&ctx->statedb.file, "%s/csync_statedb_%llu.db",
          ctx->options.config_dir, (long long unsigned int) h) < 0) {
      ctx->error_code = CSYNC_ERR_UNSPEC;
      rc = -1;
      goto out;
    }
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Remote replica: %s", ctx->remote.uri);
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Statedb: %s", ctx->statedb.file);

    if (csync_statedb_load(ctx, ctx->statedb.file) < 0) {
      ctx->error_code = CSYNC_ERR_STATEDB_LOAD;
      rc = -1;
      goto out;
    }
  }

  ctx->local.type = LOCAL_REPLICA;

  /* check for uri */
  if ( !ctx->options.local_only_mode && csync_fnmatch("*://*", ctx->remote.uri, 0) == 0) {
    size_t len;
    len = strstr(ctx->remote.uri, "://") - ctx->remote.uri;
    /* get protocol */
    if (len > 0) {
      char *module = NULL;
      /* module name */
      module = c_strndup(ctx->remote.uri, len);
      if (module == NULL) {
        ctx->error_code = CSYNC_ERR_MODULE;
        rc = -1;
        goto out;
      }
      /* load module */
retry_vio_init:
      rc = csync_vio_init(ctx, module, NULL);
      if (rc < 0) {
        len = strlen(module);

        if (len > 0 && module[len-1] == 's') {
          module[len-1] = '\0';
          goto retry_vio_init;
        }
        /* Now vio init finally failed which means a module could not be found. */
        ctx->error_code = CSYNC_ERR_MODULE;
	CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
		  "The csync module %s could not be loaded.", module);
        SAFE_FREE(module);
        goto out;
      }
      SAFE_FREE(module);
      ctx->remote.type = REMOTE_REPLCIA;
    }
  } else {
    ctx->remote.type = LOCAL_REPLICA;
  }

  if(!ctx->options.local_only_mode) {
    if(ctx->module.capabilities.time_sync_required) {
      timediff = csync_timediff(ctx);
      if (timediff > ctx->options.max_time_difference) {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
                  "Clock skew detected. The time difference is greater than %d seconds!",
                  ctx->options.max_time_difference);
        ctx->error_code = CSYNC_ERR_TIMESKEW;
        rc = -1;
        goto out;
      } else if (timediff < 0) {
        /* error code was set in csync_timediff() */
        CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Synchronisation is not possible!");
	/* do not override error code set by timediff */
	if(ctx->error_code == CSYNC_ERR_NONE) {
	  ctx->error_code = CSYNC_ERR_TIMESKEW;
	}
        rc = -1;
        goto out;
      }
    } else {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Module does not need time synchronization.");
    }

    if(ctx->module.capabilities.unix_extensions == -1) { /* detect */
      if (csync_unix_extensions(ctx) < 0) {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Could not detect filesystem type.");
        ctx->error_code = CSYNC_ERR_FILESYSTEM;
        rc = -1;
        goto out;
      }
    } else {
      /* The module specifies the value for the unix_extensions. */
      ctx->options.unix_extensions = ctx->module.capabilities.unix_extensions;
    }
  }

  if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
    ctx->error_code = CSYNC_ERR_TREE;
    rc = -1;
    goto out;
  }

  if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
    ctx->error_code = CSYNC_ERR_TREE;
    rc = -1;
    goto out;
  }

  ctx->status = CSYNC_STATUS_INIT;

  /* initialize random generator */
  srand(time(NULL));

  rc = 0;

out:
  SAFE_FREE(log);
  SAFE_FREE(lock);
  SAFE_FREE(exclude);
  SAFE_FREE(config);
  return rc;
}
Exemplo n.º 14
0
Arquivo: csync.c Projeto: gco/csync
int csync_init(CSYNC *ctx) {
  int rc;
  time_t timediff = -1;
  char *exclude = NULL;
  char *lock = NULL;
  char *config = NULL;
  char errbuf[256] = {0};
  if (ctx == NULL) {
    errno = EBADF;
    return -1;
  }

  ctx->status_code = CSYNC_STATUS_OK;

  /* Do not initialize twice */
  if (ctx->status & CSYNC_STATUS_INIT) {
    return 1;
  }

  /* create dir if it doesn't exist */
  if (! c_isdir(ctx->options.config_dir)) {
    c_mkdirs(ctx->options.config_dir, 0700);
  }

  /* create lock file */
  if (asprintf(&lock, "%s/%s", ctx->options.config_dir, CSYNC_LOCK_FILE) < 0) {
    rc = -1;
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    goto out;
  }

#ifndef _WIN32
  if (csync_lock(lock) < 0) {
    rc = -1;
    ctx->status_code = CSYNC_STATUS_NO_LOCK;
    goto out;
  }
#endif

  /* load config file */
  if (asprintf(&config, "%s/%s", ctx->options.config_dir, CSYNC_CONF_FILE) < 0) {
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    rc = -1;
    goto out;
  }

  rc = csync_config_parse_file(ctx, config);
  if (rc < 0) {
      CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Could not load config file %s, using defaults.", config);
  }

#ifndef _WIN32
  /* load global exclude list */
  if (asprintf(&exclude, "%s/csync/%s", SYSCONFDIR, CSYNC_EXCLUDE_FILE) < 0) {
    rc = -1;
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Could not load %s - %s", exclude,
              errbuf);
  }
  SAFE_FREE(exclude);
#endif
  /* load exclude list */
  if (asprintf(&exclude, "%s/%s", ctx->options.config_dir,
        CSYNC_EXCLUDE_FILE) < 0) {
    ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
    rc = -1;
    goto out;
  }

  if (csync_exclude_load(ctx, exclude) < 0) {
    strerror_r(errno, errbuf, sizeof(errbuf));
    CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Could not load %s - %s", exclude,
              errbuf);
  }

  /* create/load statedb */
  if (! csync_is_statedb_disabled(ctx)) {
    rc = asprintf(&ctx->statedb.file, "%s/.csync_journal.db",
                  ctx->local.uri);
    if (rc < 0) {
      ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
      goto out;
    }
    CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Journal: %s", ctx->statedb.file);

    rc = csync_statedb_load(ctx, ctx->statedb.file, &ctx->statedb.db);
    if (rc < 0) {
      ctx->status_code = CSYNC_STATUS_STATEDB_LOAD_ERROR;
      goto out;
    }
  }

  ctx->local.type = LOCAL_REPLICA;

  /* check for uri */
  if ( !ctx->options.local_only_mode && csync_fnmatch("*://*", ctx->remote.uri, 0) == 0) {
    size_t len;
    len = strstr(ctx->remote.uri, "://") - ctx->remote.uri;
    /* get protocol */
    if (len > 0) {
      char *module = NULL;
      /* module name */
      module = c_strndup(ctx->remote.uri, len);
      if (module == NULL) {
        rc = -1;
        ctx->status_code = CSYNC_STATUS_MEMORY_ERROR;
        goto out;
      }
      /* load module */
retry_vio_init:
      rc = csync_vio_init(ctx, module, NULL);
      if (rc < 0) {
        len = strlen(module);

        if (module[len-1] == 's') {
          module[len-1] = '\0';
          goto retry_vio_init;
        }

        SAFE_FREE(module);
        ctx->status_code = CSYNC_STATUS_NO_MODULE;
        goto out;
      }
      SAFE_FREE(module);
      ctx->remote.type = REMOTE_REPLICA;
    }
  } else {
    ctx->remote.type = LOCAL_REPLICA;
  }

  if( !ctx->options.local_only_mode ) {
      timediff = csync_timediff(ctx);
      if (timediff > ctx->options.max_time_difference) {
          CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL,
                    "Clock skew detected. The time difference is greater than %d seconds!",
                    ctx->options.max_time_difference);
          ctx->status_code = CSYNC_STATUS_TIMESKEW;
          rc = -1;
          goto out;
      } else if (timediff < 0) {
          CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Synchronisation is not possible!");
          ctx->status_code = CSYNC_STATUS_TIMESKEW;
          rc = -1;
          goto out;
      }

      if (csync_unix_extensions(ctx) < 0) {
          CSYNC_LOG(CSYNC_LOG_PRIORITY_FATAL, "Could not detect filesystem type.");
          ctx->status_code = CSYNC_STATUS_FILESYSTEM_UNKNOWN;
          rc = -1;
          goto out;
      }
  }

  /* Install progress callbacks in the module. */
  if (ctx->callbacks.file_progress_cb != NULL) {
      int prc;
      prc = csync_vio_set_property(ctx, "file_progress_callback", &ctx->callbacks.file_progress_cb);
      if (prc == -1) {
          /* The module does not support the callbacks */
          CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Could not install file progress callback!");
          ctx->callbacks.file_progress_cb = NULL;
      }
  }

  if (ctx->callbacks.overall_progress_cb != NULL) {
      int prc;
      prc = csync_vio_set_property(ctx, "overall_progress_callback", &ctx->callbacks.overall_progress_cb);
      if (prc == -1) {
          /* The module does not support the callbacks */
          CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Could not install overall progress callback!");
          ctx->callbacks.overall_progress_cb = NULL;
      }
  }

  if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  if (c_rbtree_create(&ctx->remote.tree, _key_cmp, _data_cmp) < 0) {
    ctx->status_code = CSYNC_STATUS_TREE_ERROR;
    rc = -1;
    goto out;
  }

  ctx->status = CSYNC_STATUS_INIT;

  /* initialize random generator */
  srand(time(NULL));

  rc = 0;

out:
  SAFE_FREE(lock);
  SAFE_FREE(exclude);
  SAFE_FREE(config);
  return rc;
}
Exemplo n.º 15
0
Arquivo: url.c Projeto: galdor/libhttp
struct http_url *
http_url_parse(const char *string) {
    struct http_url *url;
    const char *ptr, *start, *end, *at, *colon;
    size_t toklen;

    url = http_url_new();

    ptr = string;

#define HTTP_FAIL(fmt_, ...)              \
    do {                                  \
        c_set_error(fmt_, ##__VA_ARGS__); \
        goto error;                       \
    } while (0)

    /* Scheme */
    if (ptr[0] == '/') {
        if (ptr[1] == '/') {
            goto authority;
        } else {
            goto path;
        }
    }

    start = ptr;
    if (!(http_url_is_scheme_first_char(*ptr)))
        HTTP_FAIL("invalid first character in scheme");
    for (;;) {
        if (*ptr == '\0' || *ptr == ':') {
            toklen = (size_t)(ptr - start);
            if (toklen == 0)
                HTTP_FAIL("empty scheme");
            url->scheme = c_strndup(start, toklen);
            break;
        } else if (!http_url_is_scheme_char(*ptr)) {
            HTTP_FAIL("invalid character in scheme");
        }

        ptr++;
    }

    if (*ptr == ':')
        ptr++;

authority:
    /* Authority */
    if (ptr[0] != '/' || ptr[1] != '/')
        HTTP_FAIL("invalid characters after scheme");
    ptr += 2;

    end = ptr + strcspn(ptr, "/?#");

    at = strchr(ptr, '@');
    if (at && at < end) {
        /* User */
        colon = strchr(ptr, ':');

        if (colon) {
            toklen = (size_t)(colon - ptr);
        } else {
            toklen = (size_t)(at - ptr);
        }

        url->user = http_url_userinfo_decode(ptr, toklen);
        if (!url->user)
            HTTP_FAIL("cannot decode user: %s", c_get_error());

        if (colon) {
            /* Password */
            toklen = (size_t)(at - colon - 1);

            url->password = http_url_userinfo_decode(colon + 1, toklen);
            if (!url->password)
                HTTP_FAIL("cannot decode password: %s", c_get_error());
        }

        ptr = at + 1;
    }

    /* Host */
    if (*ptr == '[') {
        /* IPv6 address */

        ptr++;
        toklen = strcspn(ptr, "]");
    } else {
        toklen = strcspn(ptr, ":/?#");
    }

    url->host = http_url_host_decode(ptr, toklen);
    if (!url->host)
        HTTP_FAIL("cannot decode host: %s", c_get_error());

    ptr += toklen;
    if (*ptr == ']')
        ptr++;

    if (*ptr == ':') {
        size_t port_sz;

        ptr++;

        /* Port */
        toklen = strcspn(ptr, "/?#");
        if (toklen == 0)
            HTTP_FAIL("empty port number");

        url->port = c_strndup(ptr, toklen);
        if (c_parse_u16(url->port, &url->port_number, &port_sz) == -1)
            HTTP_FAIL("invalid port number: %s", c_get_error());
        if (port_sz != strlen(url->port))
            HTTP_FAIL("invalid trailing data after port number");
        if (url->port_number == 0)
            HTTP_FAIL("invalid port number");

        ptr += toklen;
    }

path:
    if (*ptr == '/') {
        /* Path */
        toklen = strcspn(ptr, "?#");
        url->path = http_url_path_decode(ptr, toklen);
        if (!url->path)
            HTTP_FAIL("cannot decode path: %s", c_get_error());

        ptr += toklen;
    }

    if (*ptr == '?') {
        ptr++;

        /* Query */
        toklen = strcspn(ptr, "#");
        url->query = c_strndup(ptr, toklen);
        if (!url->query)
            HTTP_FAIL("cannot decode query: %s", c_get_error());

        url->query_parameters = http_query_parameters_parse(url->query);
        if (!url->query_parameters)
            HTTP_FAIL("cannot parse query parameters: %s", c_get_error());

        ptr += toklen;
    }

    if (*ptr == '#') {
        ptr++;

        /* Fragment */
        toklen = strlen(ptr);
        url->fragment = http_url_fragment_decode(ptr, toklen);
        if (!url->fragment)
            HTTP_FAIL("cannot decode fragment: %s", c_get_error());

        ptr += toklen;
    }

#undef HTTP_FAIL

    return url;

error:
    http_url_delete(url);
    return NULL;
}