File: _tinysshd-install.c

package info (click to toggle)
tinyssh 20190101-1%2Bdeb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,208 kB
  • sloc: ansic: 11,914; sh: 1,005; python: 385; makefile: 18
file content (96 lines) | stat: -rw-r--r-- 2,620 bytes parent folder | download | duplicates (2)
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include "open.h"
#include "log.h"


static void usage(void) {

    log_u1("_tinysshd-install: usage: _tinysshd-install sourcefile destdir tempfile destfile [flagexecutable]");
    _exit(100);
}

static int flagtmpcreated = 0;
static const char *srcfn = 0;
static const char *tmpfn = 0;
static const char *dstfn = 0;
static const char *dstdir = 0;
static int fd1 = -1, fd2 = -1;

static void cleanup(void) {
    if (flagtmpcreated) {
        unlink(tmpfn);
    }
}

static void die_fatal(const char *trouble, const char *d, const char *fn) {

    cleanup();

    if (d) {
        if (fn) log_f5(trouble, " ", d, "/", fn);
        else log_f3(trouble, " ", d);
    }
    else {
        log_f1(trouble);
    }
    _exit(111);
}

static int flagexecutable = 0;

int main(int argc, char **argv) {

    struct stat st;
    long long r;
    char ch;

    log_init(2, "_tinysshd-install", 0, 0);

    if (argc < 5) usage();
    if (!argv[0]) usage();
    if (!argv[1]) usage();
    if (!argv[2]) usage();
    if (!argv[3]) usage();
    if (!argv[4]) usage();

    srcfn = argv[1];
    dstdir  = argv[2];
    tmpfn = argv[3];
    dstfn = argv[4];
    if (argv[5]) flagexecutable = 1;

    /* open source file */
    fd1 = open_read(srcfn);
    if (fd1 == -1) die_fatal("unable to open file", srcfn, 0);

    /* stat destination directory and change directory */
    if ((stat(dstdir, &st)) == -1) die_fatal("unable to stat directory", dstdir, 0);
    if (chdir(dstdir) == -1) die_fatal("unable to change directory to", dstdir, 0);

    /* open temporary file */
    fd2 = open_write(tmpfn);
    if (fd2 == -1) die_fatal("unable to open file", dstdir, tmpfn);
    flagtmpcreated = 1;

    /* copy file */
    for (;;) {
        r = read(fd1, &ch, 1);
        if (r == -1) die_fatal("unable to read from file", srcfn, 0);
        if (r == 0) break;
        if (write(fd2, &ch, 1) != 1) die_fatal("unable to write to file", dstdir, tmpfn);
    }
    if (fsync(fd2) == -1) die_fatal("unable to write to file", dstdir, tmpfn);
    if (fchown(fd2, st.st_uid, st.st_gid) == -1) die_fatal("unable to change owner on", dstdir, tmpfn);
    if (flagexecutable) {
        if (fchmod(fd2, 0755) == -1) die_fatal("unable to change owner on", dstdir, tmpfn);
    }
    else {
        if (fchmod(fd2, 0644) == -1) die_fatal("unable to change owner on", dstdir, tmpfn);
    }
    if (close(fd2) == -1) die_fatal("unable to write to file", dstdir, tmpfn);
    if (rename(tmpfn, dstfn) == -1) die_fatal("unable to rename file to", dstdir, dstfn);
    _exit(0);
}