156 lines
3.2 KiB
C
156 lines
3.2 KiB
C
#include <errno.h>
|
|
#include <spawn.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/wait.h>
|
|
#include <unistd.h>
|
|
#include <wait.h>
|
|
|
|
#include "intl.h"
|
|
#include "log.h"
|
|
#include "util.h"
|
|
|
|
char **env = NULL;
|
|
|
|
void set_env(char **envp) {
|
|
env = envp;
|
|
}
|
|
|
|
bool eq(char *s1, char *s2) {
|
|
if (NULL == s1 || NULL == s2)
|
|
return false;
|
|
|
|
if (strlen(s1) != strlen(s2))
|
|
return false;
|
|
|
|
return strcmp(s1, s2) == 0;
|
|
}
|
|
|
|
bool startswith(char *str, char *sub) {
|
|
size_t strl = strlen(str);
|
|
size_t subl = strlen(sub);
|
|
|
|
if (subl > strl)
|
|
return false;
|
|
|
|
return strncmp(sub, str, subl) == 0;
|
|
}
|
|
|
|
int join(char *res, const char *base, const char *pth) {
|
|
int blen = strlen(base);
|
|
|
|
if ((base[blen - 1] == '/' && pth[0] != '/') || (base[blen - 1] != '/' && pth[0] == '/')) {
|
|
return sprintf(res, "%s%s", base, pth);
|
|
} else if (base[blen - 1] != '/' && pth[0] != '/') {
|
|
return sprintf(res, "%s/%s", base, pth);
|
|
} else if (base[blen - 1] == '/' && pth[0] == '/') {
|
|
char *basedup = strdup(base);
|
|
basedup[blen - 1] = '\0';
|
|
|
|
return sprintf(res, "%s%s", basedup, pth);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
char *join_alloc(char *p1, char *p2) {
|
|
char *fp = malloc(strlen(p1) + strlen(p2) + 5);
|
|
if (!join(fp, p1, p2)) {
|
|
free(fp);
|
|
fp = NULL;
|
|
}
|
|
return fp;
|
|
}
|
|
|
|
void size_to_human(char *buf, long size) {
|
|
char *suffix[] = {"B", "KB", "MB", "GB", "TB"};
|
|
char length = sizeof(suffix) / sizeof(suffix[0]);
|
|
|
|
int i = 0;
|
|
double cursize = size;
|
|
|
|
if (size > 1024) {
|
|
for (i = 0; (size / 1024) > 0 && i < length - 1; i++, size /= 1024)
|
|
cursize = size / 1024.0;
|
|
}
|
|
|
|
sprintf(buf, "%.02lf%s", cursize, suffix[i]);
|
|
}
|
|
|
|
char *exists_in_path(char *file) {
|
|
if (NULL == file)
|
|
return NULL;
|
|
|
|
char *path = NULL, *part = NULL, *save = NULL;
|
|
size_t filesz = strlen(file);
|
|
|
|
if ((path = getenv("PATH")) == NULL)
|
|
path = "/bin";
|
|
|
|
if ((part = strtok_r(path, ":", &save)) == NULL)
|
|
return false;
|
|
|
|
do {
|
|
char fp[strlen(part) + filesz + 1];
|
|
join(fp, part, file);
|
|
|
|
if (access(fp, X_OK) == 0)
|
|
return strdup(fp);
|
|
} while ((part = strtok_r(NULL, ":", &save)) != NULL);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void editor_open(char *file) {
|
|
if (NULL == file)
|
|
return;
|
|
|
|
char *editors[] = {getenv("EDITOR"), "nano", "vi", "vim"};
|
|
int status = 0, i = 0;
|
|
char *editor = NULL;
|
|
pid_t pid = 0;
|
|
|
|
for (; i < sizeof(editors) / sizeof(char *); i++) {
|
|
if ((editor = exists_in_path(editors[i])) != NULL)
|
|
break;
|
|
}
|
|
|
|
if (NULL == editor) {
|
|
error(_("No available editor to open " FG_BOLD "%s" FG_RESET), file);
|
|
return;
|
|
}
|
|
|
|
char *argv[] = {editor, file, NULL};
|
|
|
|
if (posix_spawnp(&pid, argv[0], NULL, NULL, argv, env) != 0) {
|
|
error(_("Failed to run the editor: %s"), strerror(errno));
|
|
goto end;
|
|
}
|
|
|
|
if (waitpid(pid, &status, 0) < 0) {
|
|
error(_("Failed to open the editor: %s"), strerror(errno));
|
|
goto end;
|
|
}
|
|
|
|
end:
|
|
free(editor);
|
|
return;
|
|
}
|
|
|
|
bool can_run_install(lm_ctx_t *ctx) {
|
|
return eq(ctx->root, "/");
|
|
}
|
|
|
|
bool endswith(char *str, char *suf) {
|
|
if (NULL == str || NULL == suf)
|
|
return false;
|
|
|
|
size_t strl = strlen(str), sufl = strlen(suf);
|
|
|
|
if (sufl > strl)
|
|
return false;
|
|
|
|
return strncmp(str + strl - sufl, suf, sufl) == 0;
|
|
}
|