1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29 
30 
31 
32 #include <stdio.h>
33 #include <string.h>
34 #include <limits.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <time.h>
38 #include <sys/types.h>
39 #include "pkgstrct.h"
40 #include "pkglocale.h"
41 
42 #define	MSG_INVALID	"invalid entry"
43 
44 void
tputcfent(struct cfent * ept,FILE * fp)45 tputcfent(struct cfent *ept, FILE *fp)
46 {
47 	int	count, status;
48 	char	*pt;
49 	struct pinfo *pinfo;
50 	struct	tm	*timep;
51 	char	timeb[BUFSIZ];
52 
53 	if (ept->path == NULL)
54 		return;
55 
56 	(void) fprintf(fp, pkg_gt("Pathname: %s\n"), ept->path);
57 	(void) fprintf(fp, pkg_gt("Type: "));
58 
59 	switch (ept->ftype) {
60 	case 'f':
61 		(void) fputs(pkg_gt("regular file\n"), fp);
62 		break;
63 
64 	case 'd':
65 		(void) fputs(pkg_gt("directory\n"), fp);
66 		break;
67 
68 	case 'x':
69 		(void) fputs(pkg_gt("exclusive directory\n"), fp);
70 		break;
71 
72 	case 'v':
73 		(void) fputs(pkg_gt("volatile file\n"), fp);
74 		break;
75 
76 	case 'e':
77 		(void) fputs(pkg_gt("editted file\n"), fp);
78 		break;
79 
80 	case 'p':
81 		(void) fputs(pkg_gt("named pipe\n"), fp);
82 		break;
83 
84 	case 'i':
85 		(void) fputs(pkg_gt("installation file\n"), fp);
86 		break;
87 
88 	case 'c':
89 	case 'b':
90 		(void) fprintf(fp, pkg_gt("%s special device\n"),
91 		    (ept->ftype == 'b') ? pkg_gt("block") :
92 		    pkg_gt("character"));
93 
94 		if (ept->ainfo.major == BADMAJOR)
95 			(void) fprintf(fp, pkg_gt("Major device number: %s\n"),
96 			    MSG_INVALID);
97 		else
98 			(void) fprintf(fp, pkg_gt("Major device number: %ld\n"),
99 			    ept->ainfo.major);
100 
101 		if (ept->ainfo.minor == BADMINOR)
102 			(void) fprintf(fp, pkg_gt("Minor device number: %s\n"),
103 			    MSG_INVALID);
104 		else
105 			(void) fprintf(fp, pkg_gt("Minor device number: %ld\n"),
106 			    ept->ainfo.minor);
107 
108 		break;
109 
110 	case 'l':
111 		(void) fputs(pkg_gt("linked file\n"), fp);
112 		pt = (ept->ainfo.local ? ept->ainfo.local :
113 		    (char *)pkg_gt("(unknown)"));
114 		(void) fprintf(fp, pkg_gt("Source of link: %s\n"), pt);
115 		break;
116 
117 	case 's':
118 		(void) fputs(pkg_gt("symbolic link\n"), fp);
119 		pt = (ept->ainfo.local ? ept->ainfo.local :
120 		    (char *)pkg_gt("(unknown)"));
121 		(void) fprintf(fp, pkg_gt("Source of link: %s\n"), pt);
122 		break;
123 
124 	default:
125 		(void) fputs(pkg_gt("unknown\n"), fp);
126 		break;
127 	}
128 
129 	if (!strchr("lsin", ept->ftype)) {
130 		if (ept->ainfo.mode == BADMODE)
131 			(void) fprintf(fp, pkg_gt("Expected mode: %s\n"),
132 			    "?");
133 		else
134 			(void) fprintf(fp, pkg_gt("Expected mode: %04lo\n"),
135 			    ept->ainfo.mode);
136 
137 		(void) fprintf(fp, pkg_gt("Expected owner: %s\n"),
138 		    ept->ainfo.owner);
139 		(void) fprintf(fp, pkg_gt("Expected group: %s\n"),
140 		    ept->ainfo.group);
141 	}
142 	if (strchr("?infv", ept->ftype)) {
143 		(void) fprintf(fp,
144 		    pkg_gt("Expected file size (bytes): %llu\n"),
145 		    ept->cinfo.size);
146 		(void) fprintf(fp,
147 		    pkg_gt("Expected sum(1) of contents: %ld\n"),
148 		    ept->cinfo.cksum);
149 		if (ept->cinfo.modtime > 0) {
150 			timep = localtime(&(ept->cinfo.modtime));
151 			(void) strftime(timeb, sizeof (timeb),
152 			    pkg_gt("Expected last modification: %b %d %X %Y\n"),
153 			    timep);
154 			(void) fputs(timeb, fp);
155 		} else
156 			(void) fprintf(fp,
157 			    pkg_gt("Expected last modification: ?\n"));
158 	}
159 	if (ept->ftype == 'i') {
160 		(void) fputc('\n', fp);
161 		return;
162 	}
163 
164 	status = count = 0;
165 	if ((pinfo = ept->pinfo) != NULL) {
166 		(void) fprintf(fp,
167 		    pkg_gt("Referenced by the following packages:\n\t"));
168 		while (pinfo) {
169 			/*
170 			 * Check for partially installed object.  Need
171 			 * to explicitly check for '!', because objects
172 			 * that are provided by a server will have a
173 			 * different status character.
174 			 */
175 			if (pinfo->status == '!')
176 				status++;
177 			(void) fprintf(fp, "%-14s ", pinfo->pkg);
178 			if ((++count % 5) == 0) {
179 				(void) fputc('\n', fp);
180 				(void) fputc('\t', fp);
181 				count = 0;
182 			}
183 			pinfo = pinfo->next;
184 		}
185 		(void) fputc('\n', fp);
186 	}
187 	(void) fprintf(fp, pkg_gt("Current status: %s\n"),
188 	    status ? pkg_gt("partially installed") :
189 	    pkg_gt("installed"));
190 	(void) fputc('\n', fp);
191 }
192