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 <bluce.liguifu@huawei.com>
6 */
7 #include <string.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include "erofs/print.h"
11 #include "erofs/internal.h"
12 #include "liberofs_private.h"
13 #ifdef HAVE_SYS_IOCTL_H
14 #include <sys/ioctl.h>
15 #endif
16
17 struct erofs_configure cfg;
18 struct erofs_sb_info sbi;
19
erofs_init_configure(void)20 void erofs_init_configure(void)
21 {
22 memset(&cfg, 0, sizeof(cfg));
23
24 cfg.c_dbg_lvl = EROFS_WARN;
25 cfg.c_version = PACKAGE_VERSION;
26 cfg.c_dry_run = false;
27 cfg.c_ignore_mtime = false;
28 cfg.c_compr_level_master = -1;
29 cfg.c_force_inodeversion = 0;
30 cfg.c_inline_xattr_tolerance = 2;
31 cfg.c_unix_timestamp = -1;
32 cfg.c_uid = -1;
33 cfg.c_gid = -1;
34 cfg.c_pclusterblks_max = 1;
35 cfg.c_pclusterblks_def = 1;
36 cfg.c_max_decompressed_extent_bytes = -1;
37 }
38
erofs_show_config(void)39 void erofs_show_config(void)
40 {
41 const struct erofs_configure *c = &cfg;
42
43 if (c->c_dbg_lvl < EROFS_INFO)
44 return;
45 erofs_dump("\tc_version: [%8s]\n", c->c_version);
46 erofs_dump("\tc_dbg_lvl: [%8d]\n", c->c_dbg_lvl);
47 erofs_dump("\tc_dry_run: [%8d]\n", c->c_dry_run);
48 }
49
erofs_exit_configure(void)50 void erofs_exit_configure(void)
51 {
52 #ifdef HAVE_LIBSELINUX
53 if (cfg.sehnd)
54 selabel_close(cfg.sehnd);
55 #endif
56 if (cfg.c_img_path)
57 free(cfg.c_img_path);
58 }
59
60 static unsigned int fullpath_prefix; /* root directory prefix length */
61
erofs_set_fs_root(const char * rootdir)62 void erofs_set_fs_root(const char *rootdir)
63 {
64 fullpath_prefix = strlen(rootdir);
65 }
66
erofs_fspath(const char * fullpath)67 const char *erofs_fspath(const char *fullpath)
68 {
69 const char *s = fullpath + fullpath_prefix;
70
71 while (*s == '/')
72 s++;
73 return s;
74 }
75
76 #ifdef HAVE_LIBSELINUX
erofs_selabel_open(const char * file_contexts)77 int erofs_selabel_open(const char *file_contexts)
78 {
79 struct selinux_opt seopts[] = {
80 { .type = SELABEL_OPT_PATH, .value = file_contexts }
81 };
82
83 if (cfg.sehnd) {
84 erofs_info("ignore duplicated file contexts \"%s\"",
85 file_contexts);
86 return -EBUSY;
87 }
88
89 cfg.sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
90 if (!cfg.sehnd) {
91 erofs_err("failed to open file contexts \"%s\"",
92 file_contexts);
93 return -EINVAL;
94 }
95 return 0;
96 }
97 #endif
98
99 static bool __erofs_is_progressmsg;
100
erofs_trim_for_progressinfo(const char * str,int placeholder)101 char *erofs_trim_for_progressinfo(const char *str, int placeholder)
102 {
103 int col, len;
104
105 #ifdef GWINSZ_IN_SYS_IOCTL
106 struct winsize winsize;
107 if(ioctl(1, TIOCGWINSZ, &winsize) >= 0 &&
108 winsize.ws_col > 0)
109 col = winsize.ws_col;
110 else
111 #endif
112 col = 80;
113
114 if (col <= placeholder)
115 return strdup("");
116
117 len = strlen(str);
118 /* omit over long prefixes */
119 if (len > col - placeholder) {
120 char *s = strdup(str + len - (col - placeholder));
121
122 if (col > placeholder + 2) {
123 s[0] = '[';
124 s[1] = ']';
125 }
126 return s;
127 }
128 return strdup(str);
129 }
130
erofs_msg(int dbglv,const char * fmt,...)131 void erofs_msg(int dbglv, const char *fmt, ...)
132 {
133 va_list ap;
134 FILE *f = dbglv >= EROFS_ERR ? stderr : stdout;
135
136 if (__erofs_is_progressmsg) {
137 fputc('\n', f);
138 __erofs_is_progressmsg = false;
139 }
140 va_start(ap, fmt);
141 vfprintf(f, fmt, ap);
142 va_end(ap);
143 }
144
erofs_update_progressinfo(const char * fmt,...)145 void erofs_update_progressinfo(const char *fmt, ...)
146 {
147 char msg[8192];
148 va_list ap;
149
150 if (cfg.c_dbg_lvl >= EROFS_INFO || !cfg.c_showprogress)
151 return;
152
153 va_start(ap, fmt);
154 vsprintf(msg, fmt, ap);
155 va_end(ap);
156
157 printf("\r\033[K%s", msg);
158 __erofs_is_progressmsg = true;
159 fflush(stdout);
160 }
161