util.c revision 90153
199193Sjmallett/*
299193Sjmallett * Copyright (c) 1989, 1993, 1994
399193Sjmallett *	The Regents of the University of California.  All rights reserved.
4119071Sobrien *
5150558Skeramida * This code is derived from software contributed to Berkeley by
6109509Sjmallett * Michael Fischbein.
799193Sjmallett *
8150558Skeramida * Redistribution and use in source and binary forms, with or without
9149658Strhodes * modification, are permitted provided that the following conditions
10116087Sjmallett * are met:
11116087Sjmallett * 1. Redistributions of source code must retain the above copyright
12163835Spjd *    notice, this list of conditions and the following disclaimer.
13116087Sjmallett * 2. Redistributions in binary form must reproduce the above copyright
14116087Sjmallett *    notice, this list of conditions and the following disclaimer in the
15116087Sjmallett *    documentation and/or other materials provided with the distribution.
16116087Sjmallett * 3. All advertising materials mentioning features or use of this software
17150558Skeramida *    must display the following acknowledgement:
18150558Skeramida *	This product includes software developed by the University of
19150558Skeramida *	California, Berkeley and its contributors.
20150558Skeramida * 4. Neither the name of the University nor the names of its contributors
2199223Sjmallett *    may be used to endorse or promote products derived from this software
2299193Sjmallett *    without specific prior written permission.
2399193Sjmallett *
24150558Skeramida * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2599193Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2699193Sjmallett * 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#include <sys/types.h>
38
39__FBSDID("$FreeBSD: head/bin/ls/util.c 90153 2002-02-03 20:55:54Z markm $");
40
41#if 0
42#ifndef lint
43static char sccsid[] = "@(#)util.c	8.3 (Berkeley) 4/2/94";
44#endif /* not lint */
45#endif
46
47#include <sys/types.h>
48#include <sys/stat.h>
49
50#include <ctype.h>
51#include <err.h>
52#include <fts.h>
53#include <stdio.h>
54#include <stdlib.h>
55#include <string.h>
56
57#include "ls.h"
58#include "extern.h"
59
60int
61prn_printable(const char *s)
62{
63	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
87size_t
88len_octal(const char *s, int len)
89{
90	size_t r = 0;
91
92	while (len--)
93		if (isprint((unsigned const char)*s++)) r++; else r += 4;
94	return r;
95}
96
97int
98prn_octal(const char *s)
99{
100        unsigned char ch;
101	int len = 0;
102
103        while ((ch = (unsigned char)*s++)) {
104	        if (isprint(ch) && (ch != '\"') && (ch != '\\'))
105		        putchar(ch), len++;
106	        else if (f_octal_escape) {
107	                putchar('\\');
108		        switch (ch) {
109			case '\\':
110			        putchar('\\');
111				break;
112			case '\"':
113			        putchar('"');
114				break;
115			case '\a':
116			        putchar('a');
117				break;
118			case '\b':
119			        putchar('b');
120				break;
121			case '\f':
122			        putchar('f');
123				break;
124			case '\n':
125			        putchar('n');
126				break;
127			case '\r':
128			        putchar('r');
129				break;
130			case '\t':
131			        putchar('t');
132				break;
133			case '\v':
134			        putchar('v');
135				break;
136 		        default:
137		                putchar('0' + (ch >> 6));
138		                putchar('0' + ((ch >> 3) & 7));
139		                putchar('0' + (ch & 7));
140		                len += 2;
141			        break;
142		        }
143		        len += 2;
144	        }
145		else {
146			putchar('\\');
147	                putchar('0' + (ch >> 6));
148	                putchar('0' + ((ch >> 3) & 7));
149	                putchar('0' + (ch & 7));
150	                len += 4;
151		}
152	}
153	return len;
154}
155
156void
157usage(void)
158{
159	(void)fprintf(stderr,
160#ifdef COLORLS
161	"usage: ls [-ABCFGHLPRTWZabcdfghiklnoqrstu1]"
162#else
163	"usage: ls [-ABCFHLPRTWZabcdfghiklnoqrstu1]"
164#endif
165		      " [file ...]\n");
166	exit(1);
167}
168