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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
// SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
/*
* Copyright (C) 2018-2019 HUAWEI, Inc.
* http://www.huawei.com/
* Created by Li Guifu <bluce.liguifu@huawei.com>
*/
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include "erofs/print.h"
#include "erofs/internal.h"
#include "liberofs_private.h"
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
struct erofs_configure cfg;
struct erofs_sb_info g_sbi;
bool erofs_stdout_tty;
void erofs_init_configure(void)
{
memset(&cfg, 0, sizeof(cfg));
cfg.c_dbg_lvl = EROFS_WARN;
cfg.c_version = PACKAGE_VERSION;
cfg.c_dry_run = false;
erofs_stdout_tty = isatty(STDOUT_FILENO);
}
void erofs_show_config(void)
{
const struct erofs_configure *c = &cfg;
if (c->c_dbg_lvl < EROFS_INFO)
return;
erofs_dump("\tc_version: [%8s]\n", c->c_version);
erofs_dump("\tc_dbg_lvl: [%8d]\n", c->c_dbg_lvl);
erofs_dump("\tc_dry_run: [%8d]\n", c->c_dry_run);
}
void erofs_exit_configure(void)
{
#ifdef HAVE_LIBSELINUX
if (cfg.sehnd)
selabel_close(cfg.sehnd);
#endif
if (cfg.c_img_path)
free(cfg.c_img_path);
if (cfg.c_src_path)
free(cfg.c_src_path);
}
struct erofs_configure *erofs_get_configure()
{
return &cfg;
}
static unsigned int fullpath_prefix; /* root directory prefix length */
void erofs_set_fs_root(const char *rootdir)
{
fullpath_prefix = strlen(rootdir);
}
const char *erofs_fspath(const char *fullpath)
{
const char *s = fullpath + fullpath_prefix;
while (*s == '/')
s++;
return s;
}
#ifdef HAVE_LIBSELINUX
int erofs_selabel_open(const char *file_contexts)
{
struct selinux_opt seopts[] = {
{ .type = SELABEL_OPT_PATH, .value = file_contexts }
};
if (cfg.sehnd) {
erofs_info("ignore duplicated file contexts \"%s\"",
file_contexts);
return -EBUSY;
}
cfg.sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
if (!cfg.sehnd) {
erofs_err("failed to open file contexts \"%s\"",
file_contexts);
return -EINVAL;
}
return 0;
}
#endif
static bool __erofs_is_progressmsg;
char *erofs_trim_for_progressinfo(const char *str, int placeholder)
{
int col, len;
if (!erofs_stdout_tty) {
return strdup(str);
} else {
#ifdef GWINSZ_IN_SYS_IOCTL
struct winsize winsize;
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) >= 0 &&
winsize.ws_col > 0)
col = winsize.ws_col;
else
#endif
col = 80;
}
if (col <= placeholder)
return strdup("");
len = strlen(str);
/* omit over long prefixes */
if (len > col - placeholder) {
char *s = strdup(str + len - (col - placeholder));
if (col > placeholder + 2) {
s[0] = '[';
s[1] = ']';
}
return s;
}
return strdup(str);
}
void erofs_msg(int dbglv, const char *fmt, ...)
{
va_list ap;
FILE *f = dbglv >= EROFS_ERR ? stderr : stdout;
if (__erofs_is_progressmsg) {
fputc('\n', stdout);
__erofs_is_progressmsg = false;
}
va_start(ap, fmt);
vfprintf(f, fmt, ap);
va_end(ap);
}
void erofs_update_progressinfo(const char *fmt, ...)
{
char msg[8192];
va_list ap;
if (cfg.c_dbg_lvl >= EROFS_INFO || !cfg.c_showprogress)
return;
va_start(ap, fmt);
vsprintf(msg, fmt, ap);
va_end(ap);
if (erofs_stdout_tty) {
printf("\r\033[K%s", msg);
__erofs_is_progressmsg = true;
fflush(stdout);
return;
}
fputs(msg, stdout);
fputc('\n', stdout);
}
unsigned int erofs_get_available_processors(void)
{
#if defined(HAVE_UNISTD_H) && defined(HAVE_SYSCONF)
return sysconf(_SC_NPROCESSORS_ONLN);
#else
return 0;
#endif
}
|