xref: /illumos-gate/usr/src/contrib/ast/src/lib/libcmd/fds.c (revision b30d1939)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1992-2012 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                                                                      *
20*b30d1939SAndy Fiddaman ***********************************************************************/
21*b30d1939SAndy Fiddaman #pragma prototyped
22*b30d1939SAndy Fiddaman 
23*b30d1939SAndy Fiddaman static const char usage[] =
24*b30d1939SAndy Fiddaman "[-?\n@(#)$Id: fds (AT&T Research) 2009-09-09 $\n]"
25*b30d1939SAndy Fiddaman USAGE_LICENSE
26*b30d1939SAndy Fiddaman "[+NAME?fds - list open file descriptor status]"
27*b30d1939SAndy Fiddaman "[+DESCRIPTION?\bfds\b lists the status for each open file descriptor. "
28*b30d1939SAndy Fiddaman     "When invoked as a shell builtin it accesses the file descriptors of the "
29*b30d1939SAndy Fiddaman     "calling shell, otherwise it lists the file descriptors passed across "
30*b30d1939SAndy Fiddaman     "\bexec\b(2).]"
31*b30d1939SAndy Fiddaman "[l:long?List file descriptor details.]"
32*b30d1939SAndy Fiddaman "[u:unit?Write output to \afd\a.]#[fd]"
33*b30d1939SAndy Fiddaman "[+SEE ALSO?\blogname\b(1), \bwho\b(1), \bgetgroups\b(2), \bgetsockname\b(2), \bgetsockopts\b(2)]"
34*b30d1939SAndy Fiddaman ;
35*b30d1939SAndy Fiddaman 
36*b30d1939SAndy Fiddaman #include <cmd.h>
37*b30d1939SAndy Fiddaman #include <ls.h>
38*b30d1939SAndy Fiddaman 
39*b30d1939SAndy Fiddaman #include "FEATURE/sockets"
40*b30d1939SAndy Fiddaman 
41*b30d1939SAndy Fiddaman #if defined(S_IFSOCK) && _sys_socket && _hdr_arpa_inet && _hdr_netinet_in && _lib_getsockname && _lib_getsockopt && _lib_inet_ntoa
42*b30d1939SAndy Fiddaman #include <sys/socket.h>
43*b30d1939SAndy Fiddaman #include <netinet/in.h>
44*b30d1939SAndy Fiddaman #include <arpa/inet.h>
45*b30d1939SAndy Fiddaman #else
46*b30d1939SAndy Fiddaman #undef	S_IFSOCK
47*b30d1939SAndy Fiddaman #endif
48*b30d1939SAndy Fiddaman 
49*b30d1939SAndy Fiddaman #ifndef minor
50*b30d1939SAndy Fiddaman #define minor(x)	(int)((x)&0xff)
51*b30d1939SAndy Fiddaman #endif
52*b30d1939SAndy Fiddaman #ifndef major
53*b30d1939SAndy Fiddaman #define major(x)	(int)(((unsigned int)(x)>>8)&0xff)
54*b30d1939SAndy Fiddaman #endif
55*b30d1939SAndy Fiddaman 
56*b30d1939SAndy Fiddaman #undef	getconf
57*b30d1939SAndy Fiddaman #define getconf(x)	strtol(astconf(x,NiL,NiL),NiL,0)
58*b30d1939SAndy Fiddaman 
59*b30d1939SAndy Fiddaman #ifdef S_IFSOCK
60*b30d1939SAndy Fiddaman 
61*b30d1939SAndy Fiddaman typedef struct NV_s
62*b30d1939SAndy Fiddaman {
63*b30d1939SAndy Fiddaman 	const char*	name;
64*b30d1939SAndy Fiddaman 	int		value;
65*b30d1939SAndy Fiddaman } NV_t;
66*b30d1939SAndy Fiddaman 
67*b30d1939SAndy Fiddaman static const NV_t	family[] =
68*b30d1939SAndy Fiddaman {
69*b30d1939SAndy Fiddaman #ifdef AF_LOCAL
70*b30d1939SAndy Fiddaman 	"pipe",		AF_LOCAL,
71*b30d1939SAndy Fiddaman #endif
72*b30d1939SAndy Fiddaman #ifdef AF_UNIX
73*b30d1939SAndy Fiddaman 	"pipe",		AF_UNIX,
74*b30d1939SAndy Fiddaman #endif
75*b30d1939SAndy Fiddaman #ifdef AF_FILE
76*b30d1939SAndy Fiddaman 	"FILE",		AF_FILE,
77*b30d1939SAndy Fiddaman #endif
78*b30d1939SAndy Fiddaman #ifdef AF_INET
79*b30d1939SAndy Fiddaman 	"INET",		AF_INET,
80*b30d1939SAndy Fiddaman #endif
81*b30d1939SAndy Fiddaman #ifdef AF_AX25
82*b30d1939SAndy Fiddaman 	"AX25",		AF_AX25,
83*b30d1939SAndy Fiddaman #endif
84*b30d1939SAndy Fiddaman #ifdef AF_IPX
85*b30d1939SAndy Fiddaman 	"IPX",		AF_IPX,
86*b30d1939SAndy Fiddaman #endif
87*b30d1939SAndy Fiddaman #ifdef AF_APPLETALK
88*b30d1939SAndy Fiddaman 	"APPLETALK",	AF_APPLETALK,
89*b30d1939SAndy Fiddaman #endif
90*b30d1939SAndy Fiddaman #ifdef AF_NETROM
91*b30d1939SAndy Fiddaman 	"NETROM",	AF_NETROM,
92*b30d1939SAndy Fiddaman #endif
93*b30d1939SAndy Fiddaman #ifdef AF_BRIDGE
94*b30d1939SAndy Fiddaman 	"BRIDGE",	AF_BRIDGE,
95*b30d1939SAndy Fiddaman #endif
96*b30d1939SAndy Fiddaman #ifdef AF_ATMPVC
97*b30d1939SAndy Fiddaman 	"ATMPVC",	AF_ATMPVC,
98*b30d1939SAndy Fiddaman #endif
99*b30d1939SAndy Fiddaman #ifdef AF_X25
100*b30d1939SAndy Fiddaman 	"X25",		AF_X25,
101*b30d1939SAndy Fiddaman #endif
102*b30d1939SAndy Fiddaman #ifdef AF_INET6
103*b30d1939SAndy Fiddaman 	"INET6",	AF_INET6,
104*b30d1939SAndy Fiddaman #endif
105*b30d1939SAndy Fiddaman #ifdef AF_ROSE
106*b30d1939SAndy Fiddaman 	"ROSE",		AF_ROSE,
107*b30d1939SAndy Fiddaman #endif
108*b30d1939SAndy Fiddaman #ifdef AF_DECnet
109*b30d1939SAndy Fiddaman 	"DECnet",	AF_DECnet,
110*b30d1939SAndy Fiddaman #endif
111*b30d1939SAndy Fiddaman #ifdef AF_NETBEUI
112*b30d1939SAndy Fiddaman 	"NETBEUI",	AF_NETBEUI,
113*b30d1939SAndy Fiddaman #endif
114*b30d1939SAndy Fiddaman #ifdef AF_SECURITY
115*b30d1939SAndy Fiddaman 	"SECURITY",	AF_SECURITY,
116*b30d1939SAndy Fiddaman #endif
117*b30d1939SAndy Fiddaman #ifdef AF_KEY
118*b30d1939SAndy Fiddaman 	"KEY",		AF_KEY,
119*b30d1939SAndy Fiddaman #endif
120*b30d1939SAndy Fiddaman #ifdef AF_NETLINK
121*b30d1939SAndy Fiddaman 	"NETLINK",	AF_NETLINK,
122*b30d1939SAndy Fiddaman #endif
123*b30d1939SAndy Fiddaman #ifdef AF_ROUTE
124*b30d1939SAndy Fiddaman 	"ROUTE",	AF_ROUTE,
125*b30d1939SAndy Fiddaman #endif
126*b30d1939SAndy Fiddaman #ifdef AF_PACKET
127*b30d1939SAndy Fiddaman 	"PACKET",	AF_PACKET,
128*b30d1939SAndy Fiddaman #endif
129*b30d1939SAndy Fiddaman #ifdef AF_ASH
130*b30d1939SAndy Fiddaman 	"ASH",		AF_ASH,
131*b30d1939SAndy Fiddaman #endif
132*b30d1939SAndy Fiddaman #ifdef AF_ECONET
133*b30d1939SAndy Fiddaman 	"ECONET",	AF_ECONET,
134*b30d1939SAndy Fiddaman #endif
135*b30d1939SAndy Fiddaman #ifdef AF_ATMSVC
136*b30d1939SAndy Fiddaman 	"ATMSVC",	AF_ATMSVC,
137*b30d1939SAndy Fiddaman #endif
138*b30d1939SAndy Fiddaman #ifdef AF_SNA
139*b30d1939SAndy Fiddaman 	"SNA",		AF_SNA,
140*b30d1939SAndy Fiddaman #endif
141*b30d1939SAndy Fiddaman #ifdef AF_IRDA
142*b30d1939SAndy Fiddaman 	"IRDA",		AF_IRDA,
143*b30d1939SAndy Fiddaman #endif
144*b30d1939SAndy Fiddaman #ifdef AF_PPPOX
145*b30d1939SAndy Fiddaman 	"PPPOX",	AF_PPPOX,
146*b30d1939SAndy Fiddaman #endif
147*b30d1939SAndy Fiddaman #ifdef AF_WANPIPE
148*b30d1939SAndy Fiddaman 	"WANPIPE",	AF_WANPIPE,
149*b30d1939SAndy Fiddaman #endif
150*b30d1939SAndy Fiddaman #ifdef AF_BLUETOOTH
151*b30d1939SAndy Fiddaman 	"BLUETOOTH",	AF_BLUETOOTH,
152*b30d1939SAndy Fiddaman #endif
153*b30d1939SAndy Fiddaman 	0
154*b30d1939SAndy Fiddaman };
155*b30d1939SAndy Fiddaman 
156*b30d1939SAndy Fiddaman #endif
157*b30d1939SAndy Fiddaman 
158*b30d1939SAndy Fiddaman int
b_fds(int argc,char ** argv,Shbltin_t * context)159*b30d1939SAndy Fiddaman b_fds(int argc, char** argv, Shbltin_t* context)
160*b30d1939SAndy Fiddaman {
161*b30d1939SAndy Fiddaman 	register char*		s;
162*b30d1939SAndy Fiddaman 	register int		i;
163*b30d1939SAndy Fiddaman 	register char*		m;
164*b30d1939SAndy Fiddaman 	register char*		x;
165*b30d1939SAndy Fiddaman 	int			flags;
166*b30d1939SAndy Fiddaman 	int			details;
167*b30d1939SAndy Fiddaman 	int			open_max;
168*b30d1939SAndy Fiddaman 	int			unit;
169*b30d1939SAndy Fiddaman 	Sfio_t*			sp;
170*b30d1939SAndy Fiddaman 	struct stat		st;
171*b30d1939SAndy Fiddaman #ifdef S_IFSOCK
172*b30d1939SAndy Fiddaman 	struct sockaddr_in	addr;
173*b30d1939SAndy Fiddaman 	char*			a;
174*b30d1939SAndy Fiddaman 	unsigned char*		b;
175*b30d1939SAndy Fiddaman 	unsigned char*		e;
176*b30d1939SAndy Fiddaman 	socklen_t		addrlen;
177*b30d1939SAndy Fiddaman 	socklen_t		len;
178*b30d1939SAndy Fiddaman 	int			type;
179*b30d1939SAndy Fiddaman 	int			port;
180*b30d1939SAndy Fiddaman 	int			prot;
181*b30d1939SAndy Fiddaman 	char			num[64];
182*b30d1939SAndy Fiddaman 	char			fam[64];
183*b30d1939SAndy Fiddaman #ifdef INET6_ADDRSTRLEN
184*b30d1939SAndy Fiddaman 	char			nam[256];
185*b30d1939SAndy Fiddaman #endif
186*b30d1939SAndy Fiddaman #endif
187*b30d1939SAndy Fiddaman 
188*b30d1939SAndy Fiddaman 	cmdinit(argc, argv, context, ERROR_CATALOG, 0);
189*b30d1939SAndy Fiddaman 	details = 0;
190*b30d1939SAndy Fiddaman 	unit = 1;
191*b30d1939SAndy Fiddaman 	for (;;)
192*b30d1939SAndy Fiddaman 	{
193*b30d1939SAndy Fiddaman 		switch (optget(argv, usage))
194*b30d1939SAndy Fiddaman 		{
195*b30d1939SAndy Fiddaman 		case 'l':
196*b30d1939SAndy Fiddaman 			details = opt_info.num;
197*b30d1939SAndy Fiddaman 			continue;
198*b30d1939SAndy Fiddaman 		case 'u':
199*b30d1939SAndy Fiddaman 			unit = opt_info.num;
200*b30d1939SAndy Fiddaman 			continue;
201*b30d1939SAndy Fiddaman 		case '?':
202*b30d1939SAndy Fiddaman 			error(ERROR_USAGE|4, "%s", opt_info.arg);
203*b30d1939SAndy Fiddaman 			break;
204*b30d1939SAndy Fiddaman 		case ':':
205*b30d1939SAndy Fiddaman 			error(2, "%s", opt_info.arg);
206*b30d1939SAndy Fiddaman 			break;
207*b30d1939SAndy Fiddaman 		}
208*b30d1939SAndy Fiddaman 		break;
209*b30d1939SAndy Fiddaman 	}
210*b30d1939SAndy Fiddaman 	argv += opt_info.index;
211*b30d1939SAndy Fiddaman 	if (error_info.errors || *argv)
212*b30d1939SAndy Fiddaman 		error(ERROR_USAGE|4, "%s", optusage(NiL));
213*b30d1939SAndy Fiddaman 	if ((open_max = getconf("OPEN_MAX")) <= 0)
214*b30d1939SAndy Fiddaman 		open_max = OPEN_MAX;
215*b30d1939SAndy Fiddaman 	if (unit == 1)
216*b30d1939SAndy Fiddaman 		sp = sfstdout;
217*b30d1939SAndy Fiddaman 	else if (fstat(unit, &st) || !(sp = sfnew(NiL, NiL, SF_UNBOUND, unit, SF_WRITE)))
218*b30d1939SAndy Fiddaman 		error(ERROR_SYSTEM|3, "%d: cannot write to file descriptor");
219*b30d1939SAndy Fiddaman 	for (i = 0; i <= open_max; i++)
220*b30d1939SAndy Fiddaman 	{
221*b30d1939SAndy Fiddaman 		if (fstat(i, &st))
222*b30d1939SAndy Fiddaman 		{
223*b30d1939SAndy Fiddaman 			/* not open */
224*b30d1939SAndy Fiddaman 			continue;
225*b30d1939SAndy Fiddaman 		}
226*b30d1939SAndy Fiddaman 		if (!details)
227*b30d1939SAndy Fiddaman 		{
228*b30d1939SAndy Fiddaman 			sfprintf(sp, "%d\n", i);
229*b30d1939SAndy Fiddaman 			continue;
230*b30d1939SAndy Fiddaman 		}
231*b30d1939SAndy Fiddaman 		if ((flags = fcntl(i, F_GETFL, (char*)0)) == -1)
232*b30d1939SAndy Fiddaman 			m = "--";
233*b30d1939SAndy Fiddaman 		else
234*b30d1939SAndy Fiddaman 			switch (flags & (O_RDONLY|O_WRONLY|O_RDWR))
235*b30d1939SAndy Fiddaman 			{
236*b30d1939SAndy Fiddaman 			case O_RDONLY:
237*b30d1939SAndy Fiddaman 				m = "r-";
238*b30d1939SAndy Fiddaman 				break;
239*b30d1939SAndy Fiddaman 			case O_WRONLY:
240*b30d1939SAndy Fiddaman 				m = "-w";
241*b30d1939SAndy Fiddaman 				break;
242*b30d1939SAndy Fiddaman 			case O_RDWR:
243*b30d1939SAndy Fiddaman 				m = "rw";
244*b30d1939SAndy Fiddaman 				break;
245*b30d1939SAndy Fiddaman 			default:
246*b30d1939SAndy Fiddaman 				m = "??";
247*b30d1939SAndy Fiddaman 				break;
248*b30d1939SAndy Fiddaman 			}
249*b30d1939SAndy Fiddaman 		x = (fcntl(i, F_GETFD, (char*)0) > 0) ? "x" : "-";
250*b30d1939SAndy Fiddaman 		if (isatty(i) && (s = ttyname(i)))
251*b30d1939SAndy Fiddaman 		{
252*b30d1939SAndy Fiddaman 			sfprintf(sp, "%02d %s%s %s %s\n", i, m, x, fmtmode(st.st_mode, 0), s);
253*b30d1939SAndy Fiddaman 			continue;
254*b30d1939SAndy Fiddaman 		}
255*b30d1939SAndy Fiddaman #ifdef S_IFSOCK
256*b30d1939SAndy Fiddaman 		addrlen = sizeof(addr);
257*b30d1939SAndy Fiddaman 		memset(&addr, 0, addrlen);
258*b30d1939SAndy Fiddaman 		if (!getsockname(i, (struct sockaddr*)&addr, (void*)&addrlen))
259*b30d1939SAndy Fiddaman 		{
260*b30d1939SAndy Fiddaman 			type = 0;
261*b30d1939SAndy Fiddaman 			prot = 0;
262*b30d1939SAndy Fiddaman #ifdef SO_TYPE
263*b30d1939SAndy Fiddaman 			len = sizeof(type);
264*b30d1939SAndy Fiddaman 			if (getsockopt(i, SOL_SOCKET, SO_TYPE, (void*)&type, (void*)&len))
265*b30d1939SAndy Fiddaman 				type = -1;
266*b30d1939SAndy Fiddaman #endif
267*b30d1939SAndy Fiddaman #ifdef SO_PROTOTYPE
268*b30d1939SAndy Fiddaman 			len = sizeof(prot);
269*b30d1939SAndy Fiddaman 			if (getsockopt(i, SOL_SOCKET, SO_PROTOTYPE, (void*)&prot, (void*)&len))
270*b30d1939SAndy Fiddaman 				prot = -1;
271*b30d1939SAndy Fiddaman #endif
272*b30d1939SAndy Fiddaman 			if (!st.st_mode)
273*b30d1939SAndy Fiddaman 				st.st_mode = S_IFSOCK|S_IRUSR|S_IWUSR;
274*b30d1939SAndy Fiddaman 			s = 0;
275*b30d1939SAndy Fiddaman 			switch (type)
276*b30d1939SAndy Fiddaman 			{
277*b30d1939SAndy Fiddaman 			case SOCK_DGRAM:
278*b30d1939SAndy Fiddaman 				switch (addr.sin_family)
279*b30d1939SAndy Fiddaman 				{
280*b30d1939SAndy Fiddaman 				case AF_INET:
281*b30d1939SAndy Fiddaman #ifdef AF_INET6
282*b30d1939SAndy Fiddaman 				case AF_INET6:
283*b30d1939SAndy Fiddaman #endif
284*b30d1939SAndy Fiddaman 					s = "udp";
285*b30d1939SAndy Fiddaman 					break;
286*b30d1939SAndy Fiddaman 				}
287*b30d1939SAndy Fiddaman 				break;
288*b30d1939SAndy Fiddaman 			case SOCK_STREAM:
289*b30d1939SAndy Fiddaman 				switch (addr.sin_family)
290*b30d1939SAndy Fiddaman 				{
291*b30d1939SAndy Fiddaman 				case AF_INET:
292*b30d1939SAndy Fiddaman #ifdef AF_INET6
293*b30d1939SAndy Fiddaman 				case AF_INET6:
294*b30d1939SAndy Fiddaman #endif
295*b30d1939SAndy Fiddaman #ifdef IPPROTO_SCTP
296*b30d1939SAndy Fiddaman 					if (prot == IPPROTO_SCTP)
297*b30d1939SAndy Fiddaman 						s = "sctp";
298*b30d1939SAndy Fiddaman 					else
299*b30d1939SAndy Fiddaman #endif
300*b30d1939SAndy Fiddaman 						s = "tcp";
301*b30d1939SAndy Fiddaman 					break;
302*b30d1939SAndy Fiddaman 				}
303*b30d1939SAndy Fiddaman 				break;
304*b30d1939SAndy Fiddaman #ifdef SOCK_RAW
305*b30d1939SAndy Fiddaman 			case SOCK_RAW:
306*b30d1939SAndy Fiddaman 				s = "raw";
307*b30d1939SAndy Fiddaman 				break;
308*b30d1939SAndy Fiddaman #endif
309*b30d1939SAndy Fiddaman #ifdef SOCK_RDM
310*b30d1939SAndy Fiddaman 			case SOCK_RDM:
311*b30d1939SAndy Fiddaman 				s = "rdm";
312*b30d1939SAndy Fiddaman 				break;
313*b30d1939SAndy Fiddaman #endif
314*b30d1939SAndy Fiddaman #ifdef SOCK_SEQPACKET
315*b30d1939SAndy Fiddaman 			case SOCK_SEQPACKET:
316*b30d1939SAndy Fiddaman 				s = "seqpacket";
317*b30d1939SAndy Fiddaman 				break;
318*b30d1939SAndy Fiddaman #endif
319*b30d1939SAndy Fiddaman 			}
320*b30d1939SAndy Fiddaman 			if (!s)
321*b30d1939SAndy Fiddaman 			{
322*b30d1939SAndy Fiddaman 				for (type = 0; family[type].name && family[type].value != addr.sin_family; type++);
323*b30d1939SAndy Fiddaman 				if (!(s = (char*)family[type].name))
324*b30d1939SAndy Fiddaman 					sfsprintf(s = num, sizeof(num), "family.%d", addr.sin_family);
325*b30d1939SAndy Fiddaman 			}
326*b30d1939SAndy Fiddaman 			port = 0;
327*b30d1939SAndy Fiddaman #ifdef INET6_ADDRSTRLEN
328*b30d1939SAndy Fiddaman 			if (a = (char*)inet_ntop(addr.sin_family, &addr.sin_addr, nam, sizeof(nam)))
329*b30d1939SAndy Fiddaman 				port = ntohs(addr.sin_port);
330*b30d1939SAndy Fiddaman 			else
331*b30d1939SAndy Fiddaman #endif
332*b30d1939SAndy Fiddaman 			if (addr.sin_family == AF_INET)
333*b30d1939SAndy Fiddaman 			{
334*b30d1939SAndy Fiddaman 				a = inet_ntoa(addr.sin_addr);
335*b30d1939SAndy Fiddaman 				port = ntohs(addr.sin_port);
336*b30d1939SAndy Fiddaman 			}
337*b30d1939SAndy Fiddaman 			else
338*b30d1939SAndy Fiddaman 			{
339*b30d1939SAndy Fiddaman 				a = fam;
340*b30d1939SAndy Fiddaman 				e = (b = (unsigned char*)&addr) + addrlen;
341*b30d1939SAndy Fiddaman 				while (b < e && a < &fam[sizeof(fam)-1])
342*b30d1939SAndy Fiddaman 					a += sfsprintf(a, &fam[sizeof(fam)] - a - 1, ".%d", *b++);
343*b30d1939SAndy Fiddaman 				a = a == fam ? "0" : fam + 1;
344*b30d1939SAndy Fiddaman 			}
345*b30d1939SAndy Fiddaman 			if (port)
346*b30d1939SAndy Fiddaman 				sfprintf(sp, "%02d %s%s %s /dev/%s/%s/%d\n", i, m, x, fmtmode(st.st_mode, 0), s, a, port);
347*b30d1939SAndy Fiddaman 			else
348*b30d1939SAndy Fiddaman 				sfprintf(sp, "%02d %s%s %s /dev/%s/%s\n", i, m, x, fmtmode(st.st_mode, 0), s, a);
349*b30d1939SAndy Fiddaman 			continue;
350*b30d1939SAndy Fiddaman 		}
351*b30d1939SAndy Fiddaman #endif
352*b30d1939SAndy Fiddaman 		sfprintf(sp, "%02d %s%s %s /dev/inode/%u/%u\n", i, m, x, fmtmode(st.st_mode, 0), st.st_dev, st.st_ino);
353*b30d1939SAndy Fiddaman 	}
354*b30d1939SAndy Fiddaman 	if (sp != sfstdout)
355*b30d1939SAndy Fiddaman 	{
356*b30d1939SAndy Fiddaman 		sfsetfd(sp, -1);
357*b30d1939SAndy Fiddaman 		sfclose(sp);
358*b30d1939SAndy Fiddaman 	}
359*b30d1939SAndy Fiddaman 	return 0;
360*b30d1939SAndy Fiddaman }
361