1*33b1fccfSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
2*33b1fccfSAndroid Build Coastguard Worker /*
3*33b1fccfSAndroid Build Coastguard Worker * Copyright (C) 2018-2019 HUAWEI, Inc.
4*33b1fccfSAndroid Build Coastguard Worker * http://www.huawei.com/
5*33b1fccfSAndroid Build Coastguard Worker * Created by Li Guifu <[email protected]>
6*33b1fccfSAndroid Build Coastguard Worker */
7*33b1fccfSAndroid Build Coastguard Worker #include <string.h>
8*33b1fccfSAndroid Build Coastguard Worker #include <stdlib.h>
9*33b1fccfSAndroid Build Coastguard Worker #include <stdarg.h>
10*33b1fccfSAndroid Build Coastguard Worker #include <unistd.h>
11*33b1fccfSAndroid Build Coastguard Worker #include "erofs/print.h"
12*33b1fccfSAndroid Build Coastguard Worker #include "erofs/internal.h"
13*33b1fccfSAndroid Build Coastguard Worker #include "liberofs_private.h"
14*33b1fccfSAndroid Build Coastguard Worker #ifdef HAVE_SYS_IOCTL_H
15*33b1fccfSAndroid Build Coastguard Worker #include <sys/ioctl.h>
16*33b1fccfSAndroid Build Coastguard Worker #endif
17*33b1fccfSAndroid Build Coastguard Worker #ifdef HAVE_UNISTD_H
18*33b1fccfSAndroid Build Coastguard Worker #include <unistd.h>
19*33b1fccfSAndroid Build Coastguard Worker #endif
20*33b1fccfSAndroid Build Coastguard Worker
21*33b1fccfSAndroid Build Coastguard Worker struct erofs_configure cfg;
22*33b1fccfSAndroid Build Coastguard Worker struct erofs_sb_info g_sbi;
23*33b1fccfSAndroid Build Coastguard Worker bool erofs_stdout_tty;
24*33b1fccfSAndroid Build Coastguard Worker
erofs_init_configure(void)25*33b1fccfSAndroid Build Coastguard Worker void erofs_init_configure(void)
26*33b1fccfSAndroid Build Coastguard Worker {
27*33b1fccfSAndroid Build Coastguard Worker memset(&cfg, 0, sizeof(cfg));
28*33b1fccfSAndroid Build Coastguard Worker
29*33b1fccfSAndroid Build Coastguard Worker cfg.c_dbg_lvl = EROFS_WARN;
30*33b1fccfSAndroid Build Coastguard Worker cfg.c_version = PACKAGE_VERSION;
31*33b1fccfSAndroid Build Coastguard Worker cfg.c_dry_run = false;
32*33b1fccfSAndroid Build Coastguard Worker cfg.c_ignore_mtime = false;
33*33b1fccfSAndroid Build Coastguard Worker cfg.c_force_inodeversion = 0;
34*33b1fccfSAndroid Build Coastguard Worker cfg.c_inline_xattr_tolerance = 2;
35*33b1fccfSAndroid Build Coastguard Worker cfg.c_unix_timestamp = -1;
36*33b1fccfSAndroid Build Coastguard Worker cfg.c_uid = -1;
37*33b1fccfSAndroid Build Coastguard Worker cfg.c_gid = -1;
38*33b1fccfSAndroid Build Coastguard Worker cfg.c_max_decompressed_extent_bytes = -1;
39*33b1fccfSAndroid Build Coastguard Worker erofs_stdout_tty = isatty(STDOUT_FILENO);
40*33b1fccfSAndroid Build Coastguard Worker }
41*33b1fccfSAndroid Build Coastguard Worker
erofs_show_config(void)42*33b1fccfSAndroid Build Coastguard Worker void erofs_show_config(void)
43*33b1fccfSAndroid Build Coastguard Worker {
44*33b1fccfSAndroid Build Coastguard Worker const struct erofs_configure *c = &cfg;
45*33b1fccfSAndroid Build Coastguard Worker
46*33b1fccfSAndroid Build Coastguard Worker if (c->c_dbg_lvl < EROFS_INFO)
47*33b1fccfSAndroid Build Coastguard Worker return;
48*33b1fccfSAndroid Build Coastguard Worker erofs_dump("\tc_version: [%8s]\n", c->c_version);
49*33b1fccfSAndroid Build Coastguard Worker erofs_dump("\tc_dbg_lvl: [%8d]\n", c->c_dbg_lvl);
50*33b1fccfSAndroid Build Coastguard Worker erofs_dump("\tc_dry_run: [%8d]\n", c->c_dry_run);
51*33b1fccfSAndroid Build Coastguard Worker }
52*33b1fccfSAndroid Build Coastguard Worker
erofs_exit_configure(void)53*33b1fccfSAndroid Build Coastguard Worker void erofs_exit_configure(void)
54*33b1fccfSAndroid Build Coastguard Worker {
55*33b1fccfSAndroid Build Coastguard Worker int i;
56*33b1fccfSAndroid Build Coastguard Worker
57*33b1fccfSAndroid Build Coastguard Worker #ifdef HAVE_LIBSELINUX
58*33b1fccfSAndroid Build Coastguard Worker if (cfg.sehnd)
59*33b1fccfSAndroid Build Coastguard Worker selabel_close(cfg.sehnd);
60*33b1fccfSAndroid Build Coastguard Worker #endif
61*33b1fccfSAndroid Build Coastguard Worker if (cfg.c_img_path)
62*33b1fccfSAndroid Build Coastguard Worker free(cfg.c_img_path);
63*33b1fccfSAndroid Build Coastguard Worker if (cfg.c_src_path)
64*33b1fccfSAndroid Build Coastguard Worker free(cfg.c_src_path);
65*33b1fccfSAndroid Build Coastguard Worker for (i = 0; i < EROFS_MAX_COMPR_CFGS && cfg.c_compr_opts[i].alg; i++)
66*33b1fccfSAndroid Build Coastguard Worker free(cfg.c_compr_opts[i].alg);
67*33b1fccfSAndroid Build Coastguard Worker }
68*33b1fccfSAndroid Build Coastguard Worker
erofs_get_configure()69*33b1fccfSAndroid Build Coastguard Worker struct erofs_configure *erofs_get_configure()
70*33b1fccfSAndroid Build Coastguard Worker {
71*33b1fccfSAndroid Build Coastguard Worker return &cfg;
72*33b1fccfSAndroid Build Coastguard Worker }
73*33b1fccfSAndroid Build Coastguard Worker
74*33b1fccfSAndroid Build Coastguard Worker static unsigned int fullpath_prefix; /* root directory prefix length */
75*33b1fccfSAndroid Build Coastguard Worker
erofs_set_fs_root(const char * rootdir)76*33b1fccfSAndroid Build Coastguard Worker void erofs_set_fs_root(const char *rootdir)
77*33b1fccfSAndroid Build Coastguard Worker {
78*33b1fccfSAndroid Build Coastguard Worker fullpath_prefix = strlen(rootdir);
79*33b1fccfSAndroid Build Coastguard Worker }
80*33b1fccfSAndroid Build Coastguard Worker
erofs_fspath(const char * fullpath)81*33b1fccfSAndroid Build Coastguard Worker const char *erofs_fspath(const char *fullpath)
82*33b1fccfSAndroid Build Coastguard Worker {
83*33b1fccfSAndroid Build Coastguard Worker const char *s = fullpath + fullpath_prefix;
84*33b1fccfSAndroid Build Coastguard Worker
85*33b1fccfSAndroid Build Coastguard Worker while (*s == '/')
86*33b1fccfSAndroid Build Coastguard Worker s++;
87*33b1fccfSAndroid Build Coastguard Worker return s;
88*33b1fccfSAndroid Build Coastguard Worker }
89*33b1fccfSAndroid Build Coastguard Worker
90*33b1fccfSAndroid Build Coastguard Worker #ifdef HAVE_LIBSELINUX
erofs_selabel_open(const char * file_contexts)91*33b1fccfSAndroid Build Coastguard Worker int erofs_selabel_open(const char *file_contexts)
92*33b1fccfSAndroid Build Coastguard Worker {
93*33b1fccfSAndroid Build Coastguard Worker struct selinux_opt seopts[] = {
94*33b1fccfSAndroid Build Coastguard Worker { .type = SELABEL_OPT_PATH, .value = file_contexts }
95*33b1fccfSAndroid Build Coastguard Worker };
96*33b1fccfSAndroid Build Coastguard Worker
97*33b1fccfSAndroid Build Coastguard Worker if (cfg.sehnd) {
98*33b1fccfSAndroid Build Coastguard Worker erofs_info("ignore duplicated file contexts \"%s\"",
99*33b1fccfSAndroid Build Coastguard Worker file_contexts);
100*33b1fccfSAndroid Build Coastguard Worker return -EBUSY;
101*33b1fccfSAndroid Build Coastguard Worker }
102*33b1fccfSAndroid Build Coastguard Worker
103*33b1fccfSAndroid Build Coastguard Worker cfg.sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
104*33b1fccfSAndroid Build Coastguard Worker if (!cfg.sehnd) {
105*33b1fccfSAndroid Build Coastguard Worker erofs_err("failed to open file contexts \"%s\"",
106*33b1fccfSAndroid Build Coastguard Worker file_contexts);
107*33b1fccfSAndroid Build Coastguard Worker return -EINVAL;
108*33b1fccfSAndroid Build Coastguard Worker }
109*33b1fccfSAndroid Build Coastguard Worker return 0;
110*33b1fccfSAndroid Build Coastguard Worker }
111*33b1fccfSAndroid Build Coastguard Worker #endif
112*33b1fccfSAndroid Build Coastguard Worker
113*33b1fccfSAndroid Build Coastguard Worker static bool __erofs_is_progressmsg;
114*33b1fccfSAndroid Build Coastguard Worker
erofs_trim_for_progressinfo(const char * str,int placeholder)115*33b1fccfSAndroid Build Coastguard Worker char *erofs_trim_for_progressinfo(const char *str, int placeholder)
116*33b1fccfSAndroid Build Coastguard Worker {
117*33b1fccfSAndroid Build Coastguard Worker int col, len;
118*33b1fccfSAndroid Build Coastguard Worker
119*33b1fccfSAndroid Build Coastguard Worker if (!erofs_stdout_tty) {
120*33b1fccfSAndroid Build Coastguard Worker return strdup(str);
121*33b1fccfSAndroid Build Coastguard Worker } else {
122*33b1fccfSAndroid Build Coastguard Worker #ifdef GWINSZ_IN_SYS_IOCTL
123*33b1fccfSAndroid Build Coastguard Worker struct winsize winsize;
124*33b1fccfSAndroid Build Coastguard Worker if(ioctl(1, TIOCGWINSZ, &winsize) >= 0 &&
125*33b1fccfSAndroid Build Coastguard Worker winsize.ws_col > 0)
126*33b1fccfSAndroid Build Coastguard Worker col = winsize.ws_col;
127*33b1fccfSAndroid Build Coastguard Worker else
128*33b1fccfSAndroid Build Coastguard Worker #endif
129*33b1fccfSAndroid Build Coastguard Worker col = 80;
130*33b1fccfSAndroid Build Coastguard Worker }
131*33b1fccfSAndroid Build Coastguard Worker
132*33b1fccfSAndroid Build Coastguard Worker if (col <= placeholder)
133*33b1fccfSAndroid Build Coastguard Worker return strdup("");
134*33b1fccfSAndroid Build Coastguard Worker
135*33b1fccfSAndroid Build Coastguard Worker len = strlen(str);
136*33b1fccfSAndroid Build Coastguard Worker /* omit over long prefixes */
137*33b1fccfSAndroid Build Coastguard Worker if (len > col - placeholder) {
138*33b1fccfSAndroid Build Coastguard Worker char *s = strdup(str + len - (col - placeholder));
139*33b1fccfSAndroid Build Coastguard Worker
140*33b1fccfSAndroid Build Coastguard Worker if (col > placeholder + 2) {
141*33b1fccfSAndroid Build Coastguard Worker s[0] = '[';
142*33b1fccfSAndroid Build Coastguard Worker s[1] = ']';
143*33b1fccfSAndroid Build Coastguard Worker }
144*33b1fccfSAndroid Build Coastguard Worker return s;
145*33b1fccfSAndroid Build Coastguard Worker }
146*33b1fccfSAndroid Build Coastguard Worker return strdup(str);
147*33b1fccfSAndroid Build Coastguard Worker }
148*33b1fccfSAndroid Build Coastguard Worker
erofs_msg(int dbglv,const char * fmt,...)149*33b1fccfSAndroid Build Coastguard Worker void erofs_msg(int dbglv, const char *fmt, ...)
150*33b1fccfSAndroid Build Coastguard Worker {
151*33b1fccfSAndroid Build Coastguard Worker va_list ap;
152*33b1fccfSAndroid Build Coastguard Worker FILE *f = dbglv >= EROFS_ERR ? stderr : stdout;
153*33b1fccfSAndroid Build Coastguard Worker
154*33b1fccfSAndroid Build Coastguard Worker if (__erofs_is_progressmsg) {
155*33b1fccfSAndroid Build Coastguard Worker fputc('\n', stdout);
156*33b1fccfSAndroid Build Coastguard Worker __erofs_is_progressmsg = false;
157*33b1fccfSAndroid Build Coastguard Worker }
158*33b1fccfSAndroid Build Coastguard Worker va_start(ap, fmt);
159*33b1fccfSAndroid Build Coastguard Worker vfprintf(f, fmt, ap);
160*33b1fccfSAndroid Build Coastguard Worker va_end(ap);
161*33b1fccfSAndroid Build Coastguard Worker }
162*33b1fccfSAndroid Build Coastguard Worker
erofs_update_progressinfo(const char * fmt,...)163*33b1fccfSAndroid Build Coastguard Worker void erofs_update_progressinfo(const char *fmt, ...)
164*33b1fccfSAndroid Build Coastguard Worker {
165*33b1fccfSAndroid Build Coastguard Worker char msg[8192];
166*33b1fccfSAndroid Build Coastguard Worker va_list ap;
167*33b1fccfSAndroid Build Coastguard Worker
168*33b1fccfSAndroid Build Coastguard Worker if (cfg.c_dbg_lvl >= EROFS_INFO || !cfg.c_showprogress)
169*33b1fccfSAndroid Build Coastguard Worker return;
170*33b1fccfSAndroid Build Coastguard Worker
171*33b1fccfSAndroid Build Coastguard Worker va_start(ap, fmt);
172*33b1fccfSAndroid Build Coastguard Worker vsprintf(msg, fmt, ap);
173*33b1fccfSAndroid Build Coastguard Worker va_end(ap);
174*33b1fccfSAndroid Build Coastguard Worker
175*33b1fccfSAndroid Build Coastguard Worker if (erofs_stdout_tty) {
176*33b1fccfSAndroid Build Coastguard Worker printf("\r\033[K%s", msg);
177*33b1fccfSAndroid Build Coastguard Worker __erofs_is_progressmsg = true;
178*33b1fccfSAndroid Build Coastguard Worker fflush(stdout);
179*33b1fccfSAndroid Build Coastguard Worker return;
180*33b1fccfSAndroid Build Coastguard Worker }
181*33b1fccfSAndroid Build Coastguard Worker fputs(msg, stdout);
182*33b1fccfSAndroid Build Coastguard Worker fputc('\n', stdout);
183*33b1fccfSAndroid Build Coastguard Worker }
184*33b1fccfSAndroid Build Coastguard Worker
erofs_get_available_processors(void)185*33b1fccfSAndroid Build Coastguard Worker unsigned int erofs_get_available_processors(void)
186*33b1fccfSAndroid Build Coastguard Worker {
187*33b1fccfSAndroid Build Coastguard Worker #if defined(HAVE_UNISTD_H) && defined(HAVE_SYSCONF)
188*33b1fccfSAndroid Build Coastguard Worker return sysconf(_SC_NPROCESSORS_ONLN);
189*33b1fccfSAndroid Build Coastguard Worker #else
190*33b1fccfSAndroid Build Coastguard Worker return 0;
191*33b1fccfSAndroid Build Coastguard Worker #endif
192*33b1fccfSAndroid Build Coastguard Worker }
193