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