示例#1
0
/** atomically allocate a Message-ID unless it's already present.
 * to avoid texpire nuking the file right away, you must give another
 * file name that is linked into the Message-ID directory.
 * \return
 * - 0 for success
 * - 1 if MID already in use
 * - -1 for OS trouble.
 */
int
msgid_allocate(const char *file /** file to link into message.id */,
	const char *mid /** Non-NULL Message-ID to allocate */)
{
    char *m = lookup(mid);
    if (mkdir_parent(m, 0700))
	return 0;
    if (sync_link(file, m) == 0) {
	return 0;
    }
    if (errno == EEXIST) return 1;
    return -1;
}
示例#2
0
char* c4pkg_github_download(const char *repo)
{
  if (!repo) {
    return NULL;
  }
  
  static callback_table_t cbtable = {
    .print = printf,
    .notify = NULL,
    .start = NULL
  };
  
  char *save = NULL;
  char *url = c4pkg_github_get_package_url(repo);
  if (!url) {
    gitdl_set_error("Failed to get package url");
    return NULL;
  }
  
  const char *basename = c4pkg_net_extract_file_from_url(url);
  if (!basename) {
    gitdl_set_error("Failed to extract file name from url");
    goto fail;
  }
  
  save = string_concat(C4PKG_TMP_PATH, "/", basename, NULL);
  if (!save) {
    gitdl_set_error("Internal Error: Failed to generate tmp file path");
    goto fail;
  }
  
  if (!mkdir_parent(save, 0755)) {
    gitdl_set_error("Failed to mkdir for %s: %s", save, strerror(errno));
    goto fail;
  }
  
  if (!c4pkg_net_download(save, url, &cbtable, NULL, 10, true, false)) {
    gitdl_set_error("Failed to download package");
    goto fail;
  }
  
  return save;

fail:
  free(url);
  if (save) {
    free(save);
  }
  return NULL;
}
示例#3
0
文件: deploy-stub.c 项目: rdb/panda3d
static int mkdir_parent(const wchar_t *path) {
  // Copy the path to a temporary buffer.
  wchar_t buffer[4096];
  size_t buflen = wcslen(path);
  if (buflen + 1 >= _countof(buffer)) {
    return 0;
  }
  wcscpy_s(buffer, _countof(buffer), path);

  // Seek back to find the last path separator.
  while (buflen-- > 0) {
    if (buffer[buflen] == '/' || buffer[buflen] == '\\') {
      buffer[buflen] = 0;
      break;
    }
  }
  if (buflen == (size_t)-1 || buflen == 0) {
    // There was no path separator, or this was the root directory.
    return 0;
  }

  if (CreateDirectoryW(buffer, NULL) != 0) {
    // Success!
    return 1;
  }

  // Failed.
  DWORD last_error = GetLastError();
  if (last_error == ERROR_ALREADY_EXISTS) {
    // Not really an error: the directory is already there.
    return 1;
  }

  if (last_error == ERROR_PATH_NOT_FOUND) {
    // We need to make the parent directory first.
    if (mkdir_parent(buffer)) {
      // Parent successfully created.  Try again to make the child.
      if (CreateDirectoryW(buffer, NULL) != 0) {
        // Got it!
        return 1;
      }
    }
  }
  return 0;
}
示例#4
0
文件: deploy-stub.c 项目: rdb/panda3d
static int mkdir_parent(const char *path) {
  // Copy the path to a temporary buffer.
  char buffer[4096];
  size_t buflen = strlen(path);
  if (buflen + 1 >= sizeof(buffer)) {
    return 0;
  }
  strcpy(buffer, path);

  // Seek back to find the last path separator.
  while (buflen-- > 0) {
    if (buffer[buflen] == '/') {
      buffer[buflen] = 0;
      break;
    }
  }
  if (buflen == (size_t)-1 || buflen == 0) {
    // There was no path separator, or this was the root directory.
    return 0;
  }
  if (mkdir(buffer, 0755) == 0) {
    // Success!
    return 1;
  }

  // Failed.
  if (errno == EEXIST) {
    // Not really an error: the directory is already there.
    return 1;
  }

  if (errno == ENOENT || errno == EACCES) {
    // We need to make the parent directory first.
    if (mkdir_parent(buffer)) {
      // Parent successfully created.  Try again to make the child.
      if (mkdir(buffer, 0755) == 0) {
        // Got it!
        return 1;
      }
    }
  }
  return 0;
}
示例#5
0
文件: c4pkg_zip.c 项目: zt515/c4pkg
bool zipentry_extract_to(zipentry_t entry, const char *dir)
{
  if (!entry || !dir) {
    return false;
  }
  
  const char *name = zipentry_get_name(entry);
  size_t esz = zipentry_get_size(entry);
  
  size_t name_len = strlen(name);
  size_t dir_len = strlen(dir);
  if (name_len == 0 || dir_len == 0) {
    return false;
  }
  
  size_t total = name_len + dir_len + 1;
  bool increased = false;
  
  if (dir[dir_len - 1] != '/') {
    total++;
    increased = true;
  }
  
  char *dest_path = (char*) malloc(sizeof(char) * total);
  if (!dest_path) {
    return false;
  }
  
  memset(dest_path, '\0', total);
  strcat(dest_path, dir);
  if (increased) {
    // make sure that at least one slash in path string
    strcat(dest_path, "/");
  }
  strcat(dest_path, name);
  
  if (name[name_len - 1] == '/' && esz == 0) {
    // Is a directory, just create it.
    bool r = mkdir_recursive(dest_path, 0755);
    free(dest_path);
    return r;
  }
  
  if (!mkdir_parent(dest_path, 0755)) {
    goto fail;
  }
  
  FILE *dest = fopen(dest_path, "wb");
  if (!dest) {
    goto fail;
  }
  
  char *ebuf = (char*) malloc(sizeof(char) * (esz + 1));
  if (!ebuf) {
    goto fail_file;
  }
  
  zipentry_decompress(entry, ebuf, esz);
  ebuf[esz] = '\0';
  
  fwrite(ebuf, esz, 1, dest);
  
  fclose(dest);
  free(dest_path);
  return true;

fail_file:
  fclose(dest);
fail:
  free(dest_path);
  return false;
}
示例#6
0
文件: deploy-stub.c 项目: rdb/panda3d
/**
 * Redirects the output streams to point to the log file with the given path.
 *
 * @param path specifies the location of log file, may start with ~
 * @param append should be nonzero if it should not truncate the log file.
 */
static int setup_logging(const char *path, int append) {
#ifdef _WIN32
  // Does it start with a tilde?  Perform tilde expansion if so.
  wchar_t pathw[MAX_PATH * 2];
  size_t offset = 0;
  if (path[0] == '~' && (path[1] == 0 || path[1] == '/' || path[1] == '\\')) {
    // Strip off the tilde.
    ++path;

    // Get the home directory path for the current user.
    if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, pathw))) {
      return 0;
    }
    offset = wcslen(pathw);
  }

  // We need to convert the rest of the path from UTF-8 to UTF-16.
  if (MultiByteToWideChar(CP_UTF8, 0, path, -1, pathw + offset,
                          (int)(_countof(pathw) - offset)) == 0) {
    return 0;
  }

  DWORD access = append ? FILE_APPEND_DATA : (GENERIC_READ | GENERIC_WRITE);
  int creation = append ? OPEN_ALWAYS : CREATE_ALWAYS;
  HANDLE handle = CreateFileW(pathw, access, FILE_SHARE_DELETE | FILE_SHARE_READ,
                              NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);

  if (handle == INVALID_HANDLE_VALUE) {
    // Make the parent directories first.
    mkdir_parent(pathw);
    handle = CreateFileW(pathw, access, FILE_SHARE_DELETE | FILE_SHARE_READ,
                         NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
  }

  if (handle == INVALID_HANDLE_VALUE) {
    return 0;
  }

  if (append) {
    SetFilePointer(handle, 0, NULL, FILE_END);
  }

  SetStdHandle(STD_OUTPUT_HANDLE, handle);
  SetStdHandle(STD_ERROR_HANDLE, handle);

  // If we are running under the UCRT in a GUI application, we can't be sure
  // that we have valid fds for stdout and stderr, so we have to set them up.
  // One way to do this is to reopen them to something silly (like NUL).
  if (_fileno(stdout) < 0) {
    _close(1);
    _wfreopen(L"\\\\.\\NUL", L"w", stdout);
  }

  if (_fileno(stderr) < 0) {
    _close(2);
    _wfreopen(L"\\\\.\\NUL", L"w", stderr);
  }

  // Now replace the stdout and stderr file descriptors with one pointing to
  // our desired handle.
  int fd = _open_osfhandle((intptr_t)handle, _O_WRONLY | _O_TEXT | (append ? _O_APPEND : 0));
  _dup2(fd, _fileno(stdout));
  _dup2(fd, _fileno(stderr));
  _close(fd);

  return 1;
#else
  // Does it start with a tilde?  Perform tilde expansion if so.
  char buffer[PATH_MAX * 2];
  size_t offset = 0;
  if (path[0] == '~' && (path[1] == 0 || path[1] == '/')) {
    // Strip off the tilde.
    ++path;

    // Get the home directory path for the current user.
    const char *home_dir = getenv("HOME");
    if (home_dir == NULL) {
      home_dir = getpwuid(getuid())->pw_dir;
    }
    offset = strlen(home_dir);
    assert(offset < sizeof(buffer));
    strncpy(buffer, home_dir, sizeof(buffer));
  }

  // Copy over the rest of the path.
  strcpy(buffer + offset, path);

  mode_t mode = O_CREAT | O_WRONLY | (append ? O_APPEND : O_TRUNC);
  int fd = open(buffer, mode, 0644);
  if (fd == -1) {
    // Make the parent directories first.
    mkdir_parent(buffer);
    fd = open(buffer, mode, 0644);
  }

  if (fd == -1) {
    perror(buffer);
    return 0;
  }

  fflush(stdout);
  fflush(stderr);

  dup2(fd, 1);
  dup2(fd, 2);

  close(fd);
  return 1;
#endif
}