xref: /aosp_15_r20/external/erofs-utils/lib/config.c (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
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