aboutsummaryrefslogtreecommitdiff
path: root/src/fetch_pwd.c
blob: 7e2f2e4ebe9c4928074c70aedbee48c1a37078db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ftw.h>
#include <unistd.h>

#include "fetch_pwd.h"
#include "vars.h"

static const char *pwd_dst;

static int copy_entry(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
  (void)ftwbuf;
  const char *rel = fpath;
  if (rel[0] == '.' && rel[1] == '/') rel += 2;
  if (rel[0] == '\0') return 0;

  char dst[MAX_PATH_LEN];
  snprintf(dst, sizeof(dst), "%s/%s", pwd_dst, rel);

  if (typeflag == FTW_D) {
    mkdir(dst, 0755);
  } else if (typeflag == FTW_F) {
    int src_fd = open(fpath, O_RDONLY);
    if (src_fd < 0) return -1;

    int dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, sb->st_mode & 07777);
    if (dst_fd < 0) { close(src_fd); return -1; }

    char buf[8192];
    ssize_t n;
    while ((n = read(src_fd, buf, sizeof(buf))) > 0) {
      ssize_t written = 0;
    while (written < n) {
      ssize_t ret = write(dst_fd, buf + written, n - written);
      if (ret < 0) { close(src_fd); close(dst_fd); return -1; }
      written += ret;
    }
  }

  close(src_fd);
  close(dst_fd);
  }
  return 0;
}

void fetch_pwd(Pkg pkg) {
  pwd_dst = pkg.src;
  nftw(".", copy_entry, 64, FTW_PHYS);
}