aboutsummaryrefslogtreecommitdiff
path: root/lib/install.nim
blob: 9539a626df7eea1b063ed23caa149a102977d7ad (plain) (blame)
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
import future, os, posix, strutils

proc splitCommands(params: seq[string], index: int, res: seq[seq[string]]): seq[seq[string]] =
  if index < params.len:
    let count = params[index].parseInt
    let args = params[index + 1 .. index + count]
    splitCommands(params, index + count + 1, res & args)
  else:
    res

proc perror*(s: cstring): void {.importc, header: "<stdio.h>".}
template perror*: void = perror(paramStr(0))

proc runCommand(params: seq[string]): int =
  if params.len > 0:
    let pid = fork()
    if pid == 0:
      let cexec = allocCStringArray(params)
      let code = execvp(cexec[0], cexec)
      perror()
      deallocCStringArray(cexec)
      quit(code)
    else:
      var status: cint = 1
      discard waitpid(pid, status, 0)
      if WIFEXITED(status):
        WEXITSTATUS(status)
      else:
        discard kill(getpid(), status)
        1
  else:
    0

proc buildParams(commands: seq[seq[string]], index: int, asArg: string): seq[string] =
  if commands[index].len > 0: commands[0] & asArg & "--" & commands[index] else: @[]

proc handleInstall*(params: seq[string]): int =
  let destination = params[0]
  let uid = params[1].parseInt
  let gid = params[2].parseInt
  let paramsStart = 3

  let commands = splitCommands(params, paramsStart, @[])
  let targets = lc[x | (y <- commands[1 .. ^1], x <- y), string]

  if uid >= 0 and gid >= 0:
    for file in targets:
      try:
        let index = file.rfind("/")
        let name = if index >= 0: file[index + 1 .. ^1] else: file
        let dest = destination & "/" & name
        copyFile(file, dest)
        discard chown(dest, (Uid) uid, (Gid) gid)
      except:
        discard

  let asdepsCode = runCommand(commands.buildParams(1, "--asdeps"))
  if asdepsCode == 0:
    runCommand(commands.buildParams(2, "--asexplicit"))
  else:
    asdepsCode