util.c revision 88591
1/*
2 * Copyright (c) 1989, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Michael Fischbein.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38#if 0
39static char sccsid[] = "@(#)util.c	8.3 (Berkeley) 4/2/94";
40#else
41static const char rcsid[] =
42  "$FreeBSD: head/bin/ls/util.c 88591 2001-12-28 20:50:12Z joe $";
43#endif
44#endif /* not lint */
45
46#include <sys/types.h>
47#include <sys/stat.h>
48
49#include <ctype.h>
50#include <err.h>
51#include <fts.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55
56#include "ls.h"
57#include "extern.h"
58
59int
60prn_printable(s)
61	const char *s;
62{
63	unsigned char c;
64	int n;
65
66	for (n = 0; (c = *s) != '\0'; ++s, ++n)
67		if (isprint(c))
68			putchar(c);
69		else
70			putchar('?');
71	return n;
72}
73
74/*
75 * The fts system makes it difficult to replace fts_name with a different-
76 * sized string, so we just calculate the real length here and do the
77 * conversion in prn_octal()
78 *
79 * XXX when using f_octal_escape (-b) rather than f_octal (-B), the
80 * length computed by len_octal may be too big. I just can't be buggered
81 * to fix this as an efficient fix would involve a lookup table. Same goes
82 * for the rather inelegant code in prn_octal.
83 *
84 *                                              DES 1998/04/23
85 */
86
87int
88len_octal(s, len)
89        const char *s;
90	int len;
91{
92	int r = 0;
93
94	while (len--)
95		if (isprint((unsigned char)*s++)) r++; else r += 4;
96	return r;
97}
98
99int
100prn_octal(s)
101        const char *s;
102{
103        unsigned char ch;
104	int len = 0;
105
106        while ((ch = *s++))
107	{
108	        if (isprint(ch) && (ch != '\"') && (ch != '\\'))
109		        putchar(ch), len++;
110	        else if (f_octal_escape) {
111	                putchar('\\');
112		        switch (ch) {
113			case '\\':
114			        putchar('\\');
115				break;
116			case '\"':
117			        putchar('"');
118				break;
119			case '\a':
120			        putchar('a');
121				break;
122			case '\b':
123			        putchar('b');
124				break;
125			case '\f':
126			        putchar('f');
127				break;
128			case '\n':
129			        putchar('n');
130				break;
131			case '\r':
132			        putchar('r');
133				break;
134			case '\t':
135			        putchar('t');
136				break;
137			case '\v':
138			        putchar('v');
139				break;
140 		        default:
141		                putchar('0' + (ch >> 6));
142		                putchar('0' + ((ch >> 3) & 7));
143		                putchar('0' + (ch & 7));
144		                len += 2;
145			        break;
146		        }
147		        len += 2;
148	        }
149		else {
150			putchar('\\');
151	                putchar('0' + (ch >> 6));
152	                putchar('0' + ((ch >> 3) & 7));
153	                putchar('0' + (ch & 7));
154	                len += 4;
155		}
156	}
157	return len;
158}
159
160void
161usage()
162{
163	(void)fprintf(stderr,
164#ifdef COLORLS
165	"usage: ls [-ABCFGHLPRTWZabcdfghiklnoqrstu1]"
166#else
167	"usage: ls [-ABCFHLPRTWZabcdfghiklnoqrstu1]"
168#endif
169		      " [file ...]\n");
170	exit(1);
171}
172