Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/bin/ls/util.c
39476 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 1989, 1993, 1994
5
* The Regents of the University of California. All rights reserved.
6
*
7
* This code is derived from software contributed to Berkeley by
8
* Michael Fischbein.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*/
34
35
#include <sys/types.h>
36
#include <sys/stat.h>
37
38
#include <ctype.h>
39
#include <err.h>
40
#include <fts.h>
41
#include <limits.h>
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <string.h>
45
#include <wchar.h>
46
#include <wctype.h>
47
48
#include "ls.h"
49
#include "extern.h"
50
51
int
52
prn_normal(const char *s)
53
{
54
mbstate_t mbs;
55
wchar_t wc;
56
int i, n;
57
size_t clen;
58
59
memset(&mbs, 0, sizeof(mbs));
60
n = 0;
61
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
62
if (clen == (size_t)-2) {
63
n += printf("%s", s);
64
break;
65
}
66
if (clen == (size_t)-1) {
67
memset(&mbs, 0, sizeof(mbs));
68
putchar((unsigned char)*s);
69
s++;
70
n++;
71
continue;
72
}
73
for (i = 0; i < (int)clen; i++)
74
putchar((unsigned char)s[i]);
75
s += clen;
76
if (iswprint(wc))
77
n += wcwidth(wc);
78
}
79
return (n);
80
}
81
82
int
83
prn_printable(const char *s)
84
{
85
mbstate_t mbs;
86
wchar_t wc;
87
int i, n;
88
size_t clen;
89
90
memset(&mbs, 0, sizeof(mbs));
91
n = 0;
92
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
93
if (clen == (size_t)-1) {
94
putchar('?');
95
s++;
96
n++;
97
memset(&mbs, 0, sizeof(mbs));
98
continue;
99
}
100
if (clen == (size_t)-2) {
101
putchar('?');
102
n++;
103
break;
104
}
105
if (!iswprint(wc)) {
106
putchar('?');
107
s += clen;
108
n++;
109
continue;
110
}
111
for (i = 0; i < (int)clen; i++)
112
putchar((unsigned char)s[i]);
113
s += clen;
114
n += wcwidth(wc);
115
}
116
return (n);
117
}
118
119
/*
120
* The fts system makes it difficult to replace fts_name with a different-
121
* sized string, so we just calculate the real length here and do the
122
* conversion in prn_octal()
123
*
124
* XXX when using f_octal_escape (-b) rather than f_octal (-B), the
125
* length computed by len_octal may be too big. I just can't be buggered
126
* to fix this as an efficient fix would involve a lookup table. Same goes
127
* for the rather inelegant code in prn_octal.
128
*
129
* DES 1998/04/23
130
*/
131
132
size_t
133
len_octal(const char *s, int len)
134
{
135
mbstate_t mbs;
136
wchar_t wc;
137
size_t clen, r;
138
139
memset(&mbs, 0, sizeof(mbs));
140
r = 0;
141
while (len != 0 && (clen = mbrtowc(&wc, s, len, &mbs)) != 0) {
142
if (clen == (size_t)-1) {
143
r += 4;
144
s++;
145
len--;
146
memset(&mbs, 0, sizeof(mbs));
147
continue;
148
}
149
if (clen == (size_t)-2) {
150
r += 4 * len;
151
break;
152
}
153
if (iswprint(wc))
154
r++;
155
else
156
r += 4 * clen;
157
s += clen;
158
}
159
return (r);
160
}
161
162
int
163
prn_octal(const char *s)
164
{
165
static const char esc[] = "\\\\\"\"\aa\bb\ff\nn\rr\tt\vv";
166
const char *p;
167
mbstate_t mbs;
168
wchar_t wc;
169
size_t clen;
170
unsigned char ch;
171
int goodchar, i, len, prtlen;
172
173
memset(&mbs, 0, sizeof(mbs));
174
len = 0;
175
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
176
goodchar = clen != (size_t)-1 && clen != (size_t)-2;
177
if (goodchar && iswprint(wc) && wc != L'\"' && wc != L'\\') {
178
for (i = 0; i < (int)clen; i++)
179
putchar((unsigned char)s[i]);
180
len += wcwidth(wc);
181
} else if (goodchar && f_octal_escape &&
182
#if WCHAR_MIN < 0
183
wc >= 0 &&
184
#endif
185
wc <= (wchar_t)UCHAR_MAX &&
186
(p = strchr(esc, (char)wc)) != NULL) {
187
putchar('\\');
188
putchar(p[1]);
189
len += 2;
190
} else {
191
if (goodchar)
192
prtlen = clen;
193
else if (clen == (size_t)-1)
194
prtlen = 1;
195
else
196
prtlen = strlen(s);
197
for (i = 0; i < prtlen; i++) {
198
ch = (unsigned char)s[i];
199
putchar('\\');
200
putchar('0' + (ch >> 6));
201
putchar('0' + ((ch >> 3) & 7));
202
putchar('0' + (ch & 7));
203
len += 4;
204
}
205
}
206
if (clen == (size_t)-2)
207
break;
208
if (clen == (size_t)-1) {
209
memset(&mbs, 0, sizeof(mbs));
210
s++;
211
} else
212
s += clen;
213
}
214
return (len);
215
}
216
217
void
218
usage(void)
219
{
220
(void)fprintf(stderr,
221
#ifdef COLORLS
222
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [--color=when] [-D format] [--group-directories=]"
223
#else
224
"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [-D format] [--group-directories=]"
225
#endif
226
" [file ...]\n");
227
exit(1);
228
}
229
230