aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--lib/install.nim56
-rw-r--r--src/config.nim8
-rw-r--r--src/feature/syncinstall.nim32
-rw-r--r--src/main.nim2
-rw-r--r--src/pacman.nim40
-rw-r--r--src/utils.nim11
7 files changed, 113 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index b25ac39..3702b2c 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,7 @@ TARGETS = \
completion/bash \
completion/zsh \
lib/bisect \
+ lib/install \
src/pakku \
${MAN_PAGES}
@@ -117,6 +118,12 @@ lib/bisect: lib/bisect.nim
--nimcache:"${NIM_CACHE_DIR}/bisect" \
-o:"$@" "$<"
+lib/install: lib/install.nim
+ @echo "NIM: $@"
+ @nim c ${NIM_OPTIONS} \
+ --nimcache:"${NIM_CACHE_DIR}/install" \
+ -o:"$@" "$<"
+
src/pakku: src/main.nim $(shell find src -name \*.nim)
@echo "NIM: $@"
@nim c ${NIM_OPTIONS} \
@@ -147,6 +154,7 @@ install:
$(call install,644,'doc/pakku.8','${MANDIR}/man8/pakku.8')
$(call install,644,'doc/pakku.conf.5','${MANDIR}/man5/pakku.conf.5')
$(call install,755,'lib/bisect','${PKGLIBDIR}/bisect')
+ $(call install,755,'lib/install','${PKGLIBDIR}/install')
$(call install,755,'src/pakku','${BINDIR}/pakku')
$(call install,644,'pakku.conf','${SYSCONFDIR}/pakku.conf')
@@ -156,13 +164,14 @@ uninstall:
$(call uninstall,'${MANDIR}/man8','pakku.8')
$(call uninstall,'${MANDIR}/man5','pakku.conf.5')
$(call uninstall,'${PKGLIBDIR}','bisect')
+ $(call uninstall,'${PKGLIBDIR}','install')
$(call uninstall,'${BINDIR}','pakku')
$(call uninstall,'${SYSCONFDIR}','pakku.conf')
distcheck:
@rm -rf 'pakku-${RVERSION}'
@mkdir 'pakku-${RVERSION}'
- @for f in ${DIST}; do cp --parents $$f 'pakku-${RVERSION}'; done
+ @for f in ${DIST}; do cp -d --parents $$f 'pakku-${RVERSION}'; done
@sed -i 'pakku-${RVERSION}/Makefile' \
-e 's/^VERSION =.*/VERSION = ${RVERSION}/' \
diff --git a/lib/install.nim b/lib/install.nim
new file mode 100644
index 0000000..cec9ca1
--- /dev/null
+++ b/lib/install.nim
@@ -0,0 +1,56 @@
+import future, os, posix, sequtils, strutils
+
+let params = commandLineParams()
+let destination = params[0]
+let paramsStart = 1
+
+proc splitCommands(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(index + count + 1, res & args)
+ else:
+ res
+
+let commands = splitCommands(paramsStart, @[])
+let targets = lc[x | (y <- commands[1 .. ^1], x <- y), string]
+
+for file in targets:
+ try:
+ let index = file.rfind("/")
+ let name = if index >= 0: file[index + 1 .. ^1] else: file
+ copyFile(file, destination & "/" & name)
+ except:
+ discard
+
+proc perror*(s: cstring): void {.importc, header: "<stdio.h>".}
+template perror*: void = perror(getAppFilename())
+
+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(index: int, asArg: string): seq[string] =
+ if commands[index].len > 0: commands[0] & asArg & "--" & commands[index] else: @[]
+
+let asdepsCode = runCommand(buildParams(1, "--asdeps"))
+if asdepsCode == 0:
+ programResult = runCommand(buildParams(2, "--asexplicit"))
+else:
+ programResult = asdepsCode
diff --git a/src/config.nim b/src/config.nim
index ad57550..19dc0d6 100644
--- a/src/config.nim
+++ b/src/config.nim
@@ -21,12 +21,14 @@ type
PacmanConfig* = object of CommonConfig
rootOption*: Option[string]
dbOption*: Option[string]
+ cacheOption*: Option[string]
gpgOption*: Option[string]
colorMode*: ColorMode
Config* = object of CommonConfig
root*: string
db*: string
+ cache*: string
tmpRootInitial*: string
tmpRootCurrent*: string
color*: bool
@@ -105,12 +107,16 @@ proc db*(config: PacmanConfig): string =
let workRoot = if root == "/": "" else: root
workRoot & localStateDir & "/lib/pacman/"
+proc cache*(config: PacmanConfig): string =
+ config.cacheOption.get(localStateDir & "/cache/pacman/pkg")
+
proc obtainConfig*(config: PacmanConfig): Config =
let (configTable, _) = readConfigFile(sysConfDir & "/pakku.conf")
let options = configTable.opt("options").map(t => t[]).get(initTable[string, string]())
let root = config.root
let db = config.db
+ let cache = config.cache
let color = config.colorMode.get
proc obtainTmpDir(user: User): string =
@@ -127,7 +133,7 @@ proc obtainConfig*(config: PacmanConfig): Config =
let viewNoDefault = options.hasKey("ViewNoDefault")
let preBuildCommand = options.opt("PreBuildCommand")
- Config(root: root, db: db,
+ Config(root: root, db: db, cache: cache,
tmpRootInitial: tmpRootInitial, tmpRootCurrent: tmpRootCurrent, color: color,
dbs: config.dbs, arch: config.arch, debug: config.debug, progressBar: config.progressBar,
verbosePkgList: config.verbosePkgList, pgpKeyserver: config.pgpKeyserver,
diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim
index 2677570..1ee40c4 100644
--- a/src/feature/syncinstall.nim
+++ b/src/feature/syncinstall.nim
@@ -534,33 +534,23 @@ proc installGroupFromSources(config: Config, commonArgs: seq[Argument],
handleTmpRoot(false)
(newSeq[(string, string)](), 1)
else:
+ let pacmanParams = pacmanCmd & pacmanParams(config.color,
+ commonArgs & ("U", none(string), ArgumentType.short))
let asdeps = install.filter(p => not (p.name in explicits)).map(p => p.file)
let asexplicit = install.filter(p => p.name in explicits).map(p => p.file)
- proc doInstall(files: seq[string], addArgs: seq[Argument]): int =
- if files.len > 0:
- pacmanRun(true, config.color, commonArgs &
- ("U", none(string), ArgumentType.short) & addArgs &
- files.map(f => (f, none(string), ArgumentType.target)))
- else:
- 0
+ let installParams = sudoPrefix & (pkgLibDir & "/install") & config.cache &
+ $pacmanParams.len & pacmanParams & $asdeps.len & asdeps & $asexplicit.len & asexplicit
- let asdepsCode = doInstall(asdeps,
- @[("asdeps", none(string), ArgumentType.long)])
- if asdepsCode != 0:
+ let code = forkWait(() => execResult(installParams))
+ if code != 0:
handleTmpRoot(false)
- (newSeq[(string, string)](), asdepsCode)
+ (newSeq[(string, string)](), code)
else:
- let asexplicitCode = doInstall(asexplicit,
- @[("asexplicit", none(string), ArgumentType.long)])
- if asexplicitCode != 0:
- handleTmpRoot(false)
- (newSeq[(string, string)](), asexplicitCode)
- else:
- handleTmpRoot(true)
- let installedAs = lc[(r.name.unsafeGet, r.pkgInfo.name) | (br <- buildResults,
- r <- br.replacePkgInfos, r.name.isSome), (string, string)]
- (installedAs, 0)
+ handleTmpRoot(true)
+ let installedAs = lc[(r.name.unsafeGet, r.pkgInfo.name) | (br <- buildResults,
+ r <- br.replacePkgInfos, r.name.isSome), (string, string)]
+ (installedAs, 0)
proc deduplicatePkgInfos(pkgInfos: seq[PackageInfo],
config: Config, printWarning: bool): seq[PackageInfo] =
diff --git a/src/main.nim b/src/main.nim
index 52f1cb8..10829b8 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -90,7 +90,7 @@ proc handleSync(args: seq[Argument], config: Config): int =
let printMode = args.check(%%%"print") or args.check(%%%"print-format")
if currentUser.uid != 0 and config.sudoExec and not printMode:
- let collectedArgs = @[sudoCmd, getAppFilename()] &
+ let collectedArgs = sudoPrefix & getAppFilename() &
lc[x | (y <- args, x <- y.collectArg), string]
execResult(collectedArgs)
else:
diff --git a/src/pacman.nim b/src/pacman.nim
index 8415de8..8b85590 100644
--- a/src/pacman.nim
+++ b/src/pacman.nim
@@ -277,29 +277,20 @@ proc checkConflicts*(args: seq[Argument],
lc[(c.left, w) | (c <- conflicts, args.check(c.left.full),
w <- c.right, args.check(w.full)), (string, string)].optFirst
-proc checkExec(file: string): bool =
- var statv: Stat
- stat(file, statv) == 0 and (statv.st_mode and S_IXUSR) == S_IXUSR
-
-proc pacmanExec(root: bool, args: varargs[string]): int =
- let exec = if root and checkExec(sudoCmd):
- @[sudoCmd, pacmanCmd] & @args
- elif root and checkExec(suCmd):
- @[suCmd, "root", "-c", "exec \"$@\"", "--", "sh", pacmanCmd] & @args
- else:
- @[pacmanCmd] & @args
+proc pacmanParams*(color: bool, args: varargs[Argument]): seq[string] =
+ let colorStr = if color: "always" else: "never"
+ let argsSeq = ("color", some(colorStr), ArgumentType.long) &
+ @args.filter(arg => not arg.matchOption(%%%"color"))
+ lc[x | (y <- argsSeq, x <- y.collectArg), string]
+proc pacmanExecInternal(root: bool, params: varargs[string]): int =
+ let exec = if root: sudoPrefix & pacmanCmd & @params else: pacmanCmd & @params
execResult(exec)
proc pacmanExec*(root: bool, color: bool, args: varargs[Argument]): int =
let useRoot = root and getuid() != 0
- let colorStr = if color: "always" else: "never"
-
- let argsSeq = ("color", some(colorStr), ArgumentType.long) &
- @args.filter(arg => not arg.matchOption(%%%"color"))
- let collectedArgs = lc[x | (y <- argsSeq, x <- y.collectArg), string]
-
- pacmanExec(useRoot, collectedArgs)
+ let params = pacmanParams(color, args)
+ pacmanExecInternal(useRoot, params)
proc pacmanRun*(root: bool, color: bool, args: varargs[Argument]): int =
let argsSeq = @args
@@ -308,7 +299,7 @@ proc pacmanRun*(root: bool, color: bool, args: varargs[Argument]): int =
proc pacmanValidateAndThrow(args: varargs[Argument]): void =
let argsSeq = @args
let collectedArgs = lc[x | (y <- argsSeq, x <- y.collectArg), string]
- let code = forkWait(() => pacmanExec(false, "-T" & collectedArgs))
+ let code = forkWait(() => pacmanExecInternal(false, "-T" & collectedArgs))
if code != 0:
raise haltError(code)
@@ -320,6 +311,7 @@ proc getMachineName: Option[string] =
proc createConfigFromTable(table: Table[string, string], dbs: seq[string]): PacmanConfig =
let root = table.opt("RootDir")
let db = table.opt("DBPath")
+ let cache = table.opt("CacheDir")
let gpg = table.opt("GPGDir")
let color = if table.hasKey("Color"): ColorMode.colorAuto else: ColorMode.colorNever
let verbosePkgList = table.hasKey("VerbosePkgLists")
@@ -332,9 +324,10 @@ proc createConfigFromTable(table: Table[string, string], dbs: seq[string]): Pacm
raise commandError(tr"can not get the architecture",
colorNeeded = some(color.get))
- PacmanConfig(rootOption: root, dbOption: db, gpgOption: gpg, dbs: dbs, arch: archFinal,
- colorMode: color, debug: false, progressBar: true, verbosePkgList: verbosePkgList,
- pgpKeyserver: none(string), ignorePkgs: ignorePkgs, ignoreGroups: ignoreGroups)
+ PacmanConfig(rootOption: root, dbOption: db, cacheOption: cache, gpgOption: gpg,
+ dbs: dbs, arch: archFinal, colorMode: color, debug: false, progressBar: true,
+ verbosePkgList: verbosePkgList, pgpKeyserver: none(string),
+ ignorePkgs: ignorePkgs, ignoreGroups: ignoreGroups)
proc obtainPacmanConfig*(args: seq[Argument]): PacmanConfig =
proc getAll(pair: OptionPair): seq[string] =
@@ -356,6 +349,7 @@ proc obtainPacmanConfig*(args: seq[Argument]): PacmanConfig =
let root = getAll(%%%"root").optLast.orElse(defaultConfig.rootOption)
let db = getAll(%%%"dbpath").optLast.orElse(defaultConfig.dbOption)
+ let cache = getAll(%%%"cachedir").optLast.orElse(defaultConfig.cacheOption)
let gpg = getAll(%%%"gpgdir").optLast.orElse(defaultConfig.gpgOption)
let arch = getAll(%%%"arch").optLast.get(defaultConfig.arch)
let colorStr = getAll(%%%"color").optLast.get($defaultConfig.colorMode)
@@ -398,7 +392,7 @@ proc obtainPacmanConfig*(args: seq[Argument]): PacmanConfig =
file.close()
pgpKeyserver)
- let config = PacmanConfig(rootOption: root, dbOption: db, gpgOption: gpg,
+ let config = PacmanConfig(rootOption: root, dbOption: db, cacheOption: cache, gpgOption: gpg,
dbs: defaultConfig.dbs, arch: arch, colorMode: color, debug: debug,
progressBar: progressBar, verbosePkgList: defaultConfig.verbosePkgList,
pgpKeyserver: pgpKeyserver, ignorePkgs: ignorePkgs + defaultConfig.ignorePkgs,
diff --git a/src/utils.nim b/src/utils.nim
index b480ce9..7dcf620 100644
--- a/src/utils.nim
+++ b/src/utils.nim
@@ -285,6 +285,17 @@ proc dropPrivileges*(): bool =
else:
return true
+proc checkExec(file: string): bool =
+ var statv: Stat
+ stat(file, statv) == 0 and (statv.st_mode and S_IXUSR) == S_IXUSR
+
+let sudoPrefix*: seq[string] = if checkExec(sudoCmd):
+ @[sudoCmd]
+ elif checkExec(suCmd):
+ @[suCmd, "root", "-c", "exec \"$@\"", "--", "sh"]
+ else:
+ @[]
+
var intSigact: SigAction
intSigact.sa_handler = SIG_DFL
discard sigaction(SIGINT, intSigact)