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