镜像自地址
https://github.com/JGZYES/ParlzPackageManger.git
已同步 2026-09-11 05:42:44 +08:00
feat: pmm system-install mode (default) — /usr/bin, /etc/pmm, system lib, no env vars
Default (no -p) now installs like a system package manager: - pmm config/db -> /etc/pmm, cache -> /var/cache/pmm, pmm binary -> /usr/bin. - .pdm data routed by type: bin -> /usr/bin, lib -> /usr/lib/<pkg-subpath>, etc -> /etc/pmm/<pkg>, else -> /usr/share/pmm/<pkg>; then ldconfig. - pmm_remove removes the recorded absolute system dests. - pmm_add_to_path is a no-op in system mode (system paths are auto-found); the -p <path> local mode keeps the old ~/.pmm + PATH/LD_LIBRARY_PATH behavior. Verified: routing moves (no double multiarch), and -p local mode still writes env.
这个提交包含在:
+2
-2
文件差异因一行或多行过长而隐藏
@@ -597,6 +597,34 @@ int pdm_install_file(const char *pdmfile) {
|
|||||||
flatten_bin("."); /* cwd = the install address in flat mode */
|
flatten_bin("."); /* cwd = the install address in flat mode */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* system-install mode (default, no -p): route the staged files to system
|
||||||
|
* destinations (ELF->/usr/bin, .so->system lib dir, etc->/etc/pmm/<pkg>,
|
||||||
|
* else->/usr/share/pmm/<pkg>) and record the absolute dest paths for remove. */
|
||||||
|
int sys_mode = (!flat && pmm_system_mode());
|
||||||
|
char destfile[1500];
|
||||||
|
if (sys_mode) {
|
||||||
|
snprintf(destfile, sizeof(destfile), "%s/.pmm-dests.txt", home);
|
||||||
|
char cmd2[9000];
|
||||||
|
snprintf(cmd2, sizeof(cmd2),
|
||||||
|
"DESTFILE=\"%s\"; cd \"%s\" && : > \"$DESTFILE\" && "
|
||||||
|
"MULTI=$(uname -m | sed 's/x86_64/x86_64-linux-gnu/; s/aarch64/aarch64-linux-gnu/; s/armv7l/arm-linux-gnueabihf/'); "
|
||||||
|
"[ -n \"$MULTI\" ] || MULTI=x86_64-linux-gnu; "
|
||||||
|
"find . -type f | while IFS= read -r f; do "
|
||||||
|
"rel=${f#./}; "
|
||||||
|
"case \"$rel\" in "
|
||||||
|
"bin/*) d=\"/usr/bin/${rel#bin/}\"; mkdir -p \"$(dirname \"$d\")\"; mv -f \"$f\" \"$d\"; echo \"$d\" >> \"$DESTFILE\";; "
|
||||||
|
"lib/*) d=\"/usr/lib/${rel#lib/}\"; mkdir -p \"$(dirname \"$d\")\"; mv -f \"$f\" \"$d\"; echo \"$d\" >> \"$DESTFILE\";; "
|
||||||
|
"etc/*) d=\"/etc/pmm/%s/${rel#etc/}\"; mkdir -p \"$(dirname \"$d\")\"; mv -f \"$f\" \"$d\"; echo \"$d\" >> \"$DESTFILE\";; "
|
||||||
|
"usr/*) d=\"/usr/${rel#usr/}\"; mkdir -p \"$(dirname \"$d\")\"; mv -f \"$f\" \"$d\"; echo \"$d\" >> \"$DESTFILE\";; "
|
||||||
|
"*) d=\"/usr/share/pmm/%s/$rel\"; mkdir -p \"$(dirname \"$d\")\"; mv -f \"$f\" \"$d\"; echo \"$d\" >> \"$DESTFILE\";; "
|
||||||
|
"esac; done; ldconfig 2>/dev/null || true; "
|
||||||
|
"chmod -f +x /usr/bin/* >/dev/null 2>&1 || true",
|
||||||
|
destfile, root, pkg, pkg);
|
||||||
|
if (system(cmd2) != 0) {
|
||||||
|
pmm_warn("%s", pmm_tr_fmt("msg.warn.system-route", pkg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* record file list + control in db */
|
/* record file list + control in db */
|
||||||
snprintf(cmd, sizeof(cmd), "%s/%s.info", db, pkg);
|
snprintf(cmd, sizeof(cmd), "%s/%s.info", db, pkg);
|
||||||
FILE *dbf = fopen(cmd, "wb"); /* binary: keep \n, avoid Windows CRLF translation */
|
FILE *dbf = fopen(cmd, "wb"); /* binary: keep \n, avoid Windows CRLF translation */
|
||||||
@@ -604,22 +632,33 @@ int pdm_install_file(const char *pdmfile) {
|
|||||||
fprintf(dbf, "Package: %s\nVersion: %s\nSource: %s\n\n%s\n",
|
fprintf(dbf, "Package: %s\nVersion: %s\nSource: %s\n\n%s\n",
|
||||||
pkg, ver ? ver : "0.0.0", base_name(pdmfile), ctl);
|
pkg, ver ? ver : "0.0.0", base_name(pdmfile), ctl);
|
||||||
fprintf(dbf, "Files:\n");
|
fprintf(dbf, "Files:\n");
|
||||||
char ltcmd[2600];
|
if (sys_mode) {
|
||||||
snprintf(ltcmd, sizeof(ltcmd), "tar -tzf \"%s/data.tar.gz\"", stage);
|
FILE *df = fopen(destfile, "r");
|
||||||
FILE *tf = PMM_POPEN_READ(ltcmd);
|
if (df) {
|
||||||
if (tf) {
|
char ln[2048];
|
||||||
char ln[2048];
|
while (fgets(ln, sizeof(ln), df)) fputs(ln, dbf);
|
||||||
while (fgets(ln, sizeof(ln), tf)) {
|
fclose(df);
|
||||||
if (flat) { /* reflection of the flatten: strip a leading bin/ */
|
} else {
|
||||||
const char *q = ln;
|
pmm_warn(pmm_tr("msg.warn.no-filelist"));
|
||||||
while (*q==' '||*q=='\t') q++;
|
|
||||||
if (q[0]=='.'&&q[1]=='/'&&strncasecmp(q+2,"bin/",4)==0) { ln[0]='\0'; continue; }
|
|
||||||
}
|
|
||||||
fputs(ln, dbf);
|
|
||||||
}
|
}
|
||||||
PMM_PCLOSE_READ(tf);
|
|
||||||
} else {
|
} else {
|
||||||
pmm_warn(pmm_tr("msg.warn.no-filelist"));
|
char ltcmd[2600];
|
||||||
|
snprintf(ltcmd, sizeof(ltcmd), "tar -tzf \"%s/data.tar.gz\"", stage);
|
||||||
|
FILE *tf = PMM_POPEN_READ(ltcmd);
|
||||||
|
if (tf) {
|
||||||
|
char ln[2048];
|
||||||
|
while (fgets(ln, sizeof(ln), tf)) {
|
||||||
|
if (flat) { /* reflection of the flatten: strip a leading bin/ */
|
||||||
|
const char *q = ln;
|
||||||
|
while (*q==' '||*q=='\t') q++;
|
||||||
|
if (q[0]=='.'&&q[1]=='/'&&strncasecmp(q+2,"bin/",4)==0) { ln[0]='\0'; continue; }
|
||||||
|
}
|
||||||
|
fputs(ln, dbf);
|
||||||
|
}
|
||||||
|
PMM_PCLOSE_READ(tf);
|
||||||
|
} else {
|
||||||
|
pmm_warn(pmm_tr("msg.warn.no-filelist"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(dbf);
|
fclose(dbf);
|
||||||
}
|
}
|
||||||
@@ -747,7 +786,8 @@ int pdm_remove(const char *name) {
|
|||||||
char *p = path;
|
char *p = path;
|
||||||
while (p[0] == '.' && p[1] == '/') p += 2;
|
while (p[0] == '.' && p[1] == '/') p += 2;
|
||||||
char full[1200];
|
char full[1200];
|
||||||
snprintf(full, sizeof(full), "%s/%s", root, p);
|
if (p[0] == '/') { snprintf(full, sizeof(full), "%s", p); } /* system-mode absolute dest */
|
||||||
|
else snprintf(full, sizeof(full), "%s/%s", root, p);
|
||||||
remove(full);
|
remove(full);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,6 +149,16 @@ void pmm_set_install_path(const char *path) {
|
|||||||
}
|
}
|
||||||
int pmm_flat_mode(void) { return g_base_path[0] ? 1 : 0; }
|
int pmm_flat_mode(void) { return g_base_path[0] ? 1 : 0; }
|
||||||
|
|
||||||
|
/* System-install mode: unix default (no -p <path>). Writes to /usr/bin, /etc/pmm,
|
||||||
|
* the system lib dir and /usr/share/pmm — no PATH/LD_LIBRARY_PATH needed. */
|
||||||
|
int pmm_system_mode(void) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
return 0; /* Windows always uses local mode */
|
||||||
|
#else
|
||||||
|
return g_base_path[0] ? 0 : 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Resolve the .pmm base dir: explicit drive override > persisted drive >
|
/* Resolve the .pmm base dir: explicit drive override > persisted drive >
|
||||||
* home/.pmm (when that drive is picked) > DEFAULT = D:\.pmm.
|
* home/.pmm (when that drive is picked) > DEFAULT = D:\.pmm.
|
||||||
* Defaulting to D:\ spares the C: drive (user's primary diskspace concern);
|
* Defaulting to D:\ spares the C: drive (user's primary diskspace concern);
|
||||||
@@ -188,7 +198,7 @@ static const char *pmm_base_dir(char *buf, size_t size) {
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
snprintf(buf, size, "D:\\.pmm"); /* Windows DEFAULT -> D: */
|
snprintf(buf, size, "D:\\.pmm"); /* Windows DEFAULT -> D: */
|
||||||
#else
|
#else
|
||||||
snprintf(buf, size, "%s/.pmm", home_dir()); /* unix default -> ~/.pmm */
|
snprintf(buf, size, "/etc/pmm"); /* unix default -> system config dir */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
@@ -201,6 +211,7 @@ const char *pmm_config_dir(char *buf, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *pmm_cache_dir(char *buf, size_t size) {
|
const char *pmm_cache_dir(char *buf, size_t size) {
|
||||||
|
if (pmm_system_mode()) { snprintf(buf, size, "/var/cache/pmm"); mkdir_p(buf); return buf; }
|
||||||
char base[1024];
|
char base[1024];
|
||||||
pmm_base_dir(base, sizeof(base));
|
pmm_base_dir(base, sizeof(base));
|
||||||
snprintf(buf, size, "%s/cache", base);
|
snprintf(buf, size, "%s/cache", base);
|
||||||
@@ -219,7 +230,7 @@ const char *pmm_install_dir(char *buf, size_t size) {
|
|||||||
pmm_base_dir(base, sizeof(base));
|
pmm_base_dir(base, sizeof(base));
|
||||||
snprintf(buf, size, "%s/bin", base); /* Windows default -> <base>\bin */
|
snprintf(buf, size, "%s/bin", base); /* Windows default -> <base>\bin */
|
||||||
#else
|
#else
|
||||||
snprintf(buf, size, "/usr/local/bin"); /* Linux/macOS default -> system-wide (on PATH) */
|
snprintf(buf, size, "/usr/bin"); /* Linux/macOS default -> system-wide (on PATH) */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
mkdir_p(buf);
|
mkdir_p(buf);
|
||||||
@@ -300,6 +311,7 @@ static void add_path_candidate(char list[][1200], int *n, int max, const char *d
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pmm_add_to_path(void) {
|
void pmm_add_to_path(void) {
|
||||||
|
if (pmm_system_mode()) return; /* system mode: /usr/bin & system libs are already found */
|
||||||
char home[1024];
|
char home[1024];
|
||||||
pmm_config_dir(home, sizeof(home));
|
pmm_config_dir(home, sizeof(home));
|
||||||
char base[1024];
|
char base[1024];
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ void pmm_set_install_path(const char *path);
|
|||||||
* into that directory (files flattened), without a root/bin sub-folder. */
|
* into that directory (files flattened), without a root/bin sub-folder. */
|
||||||
int pmm_flat_mode(void);
|
int pmm_flat_mode(void);
|
||||||
|
|
||||||
|
/* 1 if running in system-install mode (unix default, no -p): files go to
|
||||||
|
* /usr/bin, /etc/pmm, the system lib dir; no PATH/LD_LIBRARY_PATH is written. */
|
||||||
|
int pmm_system_mode(void);
|
||||||
|
|
||||||
/* File-association record written to the per-user registry on install. */
|
/* File-association record written to the per-user registry on install. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *progid; /* e.g. "Node.JSFile" */
|
const char *progid; /* e.g. "Node.JSFile" */
|
||||||
|
|||||||
@@ -137,5 +137,6 @@
|
|||||||
"msg.err.not-cached": "%s not in cache (run pmm fetch)",
|
"msg.err.not-cached": "%s not in cache (run pmm fetch)",
|
||||||
"msg.postinst-ok": "post-install script ran OK: %s",
|
"msg.postinst-ok": "post-install script ran OK: %s",
|
||||||
"msg.warn.postinst": "post-install script returned non-zero: %s",
|
"msg.warn.postinst": "post-install script returned non-zero: %s",
|
||||||
"msg.warn.postinst-missing": "post-install script missing: %s"
|
"msg.warn.postinst-missing": "post-install script missing: %s",
|
||||||
|
"msg.warn.system-route": "some files failed to route to system paths: %s"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,5 +137,6 @@
|
|||||||
"msg.err.not-cached": "%s 未在缓存中(先运行 pmm fetch)",
|
"msg.err.not-cached": "%s 未在缓存中(先运行 pmm fetch)",
|
||||||
"msg.postinst-ok": "安装后脚本执行成功: %s",
|
"msg.postinst-ok": "安装后脚本执行成功: %s",
|
||||||
"msg.warn.postinst": "安装后脚本返回非 0: %s",
|
"msg.warn.postinst": "安装后脚本返回非 0: %s",
|
||||||
"msg.warn.postinst-missing": "安装后脚本缺失: %s"
|
"msg.warn.postinst-missing": "安装后脚本缺失: %s",
|
||||||
|
"msg.warn.system-route": "安装后路由到系统路径时部分失败: %s"
|
||||||
}
|
}
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户