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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 #include <sys/syscall.h>
32 #include <sys/param.h>
33 #include <sys/sysmacros.h>
34 #include <sys/types.h>
37 #include "s5sysmacros.h"
40 #define PRINTER_DIR "/etc/lp/printers/"
41 #define PRINTER_CONFIG_FILE "/configuration"
42 #define MNT_LINE_MAX 1024
44 #define GETTOK(xx, ll) \
45 if ((xx = strtok(ll, sepstr)) == NULL) \
47 if (strcmp(xx, dash) == 0) \
52 static void getPrinterInfo(char *, FILE *);
53 static char sepstr
[] = " \t\n";
54 static char dash
[] = "-";
55 static int open_printcap(void);
57 /* SVR4/SunOS 5.0 equivalent modes */
58 #define N_O_NDELAY 0x04
60 #define N_O_NONBLOCK 0x80
61 #define N_O_CREAT 0x100
62 #define N_O_TRUNC 0x200
63 #define N_O_EXCL 0x400
65 /* Mask corresponding to the bits above in SunOS 4.x */
66 #define FLAGS_MASK (O_SYNC|O_NONBLOCK|O_CREAT|O_TRUNC|O_EXCL \
70 open_com(char *path
, int flags
, int mode
)
72 int fd
, fd2
, pathl
, inspt
, ret
= 0;
74 char loc
[] = "/lib/locale";
77 if (flags
& FLAGS_MASK
) {
78 nflags
= flags
& ~FLAGS_MASK
;
81 if (flags
& (_FNDELAY
|O_NONBLOCK
)) {
82 nflags
|= N_O_NONBLOCK
;
94 /* change path from ..../lib/locale/.... to ..../lib/oldlocale/.... XXX */
96 if ((loct
= (char *)_strstr(path
, loc
)) != NULL
) { /* /lib/locale ? */
97 char locbuf
[MAXPATHLEN
+100]; /* to hold new locale path */
100 inspt
= pathl
- strlen(loct
) + 5; /* pos to add "old" */
101 (void) strncpy(locbuf
, path
, inspt
); /* copy path upto lib */
102 locbuf
[inspt
] = '\0'; /* make it a string */
103 strcat(locbuf
, "old"); /* add "old" */
104 strcat(locbuf
, loct
+5); /* add remainer of path */
105 return (_syscall(SYS_openat
, AT_FDCWD
, locbuf
, nflags
, mode
));
108 if (strcmp(path
, "/etc/mtab") == 0)
109 return (open_mnt("/etc/mnttab", "mtab", nflags
, mode
));
111 if (strcmp(path
, "/etc/fstab") == 0)
112 return (open_mnt("/etc/vfstab", "fstab", nflags
, mode
));
114 if (strcmp(path
, "/etc/printcap") == 0) {
115 if ((fd
= _syscall(SYS_openat
, AT_FDCWD
, path
, nflags
, mode
))
118 return (open_printcap());
121 if (strcmp(path
, "/etc/utmp") == 0 ||
122 strcmp(path
, "/var/adm/utmp") == 0) {
123 fd
= _syscall(SYS_openat
,
124 AT_FDCWD
, "/var/adm/utmpx", nflags
, mode
);
126 fd_add(fd
, UTMPX_MAGIC_FLAG
);
130 if (strcmp(path
, "/var/adm/wtmp") == 0) {
131 fd
= _syscall(SYS_openat
,
132 AT_FDCWD
, "/var/adm/wtmpx", nflags
, mode
);
134 fd_add(fd
, UTMPX_MAGIC_FLAG
);
138 return (_syscall(SYS_openat
, AT_FDCWD
, path
, nflags
, mode
));
142 open_mnt(char *fname
, char *tname
, int flags
, int mode
)
144 FILE *fd_in
, *fd_out
;
147 char line
[MNT_LINE_MAX
];
150 if ((fd_in
= _fopen(fname
, "r")) == NULL
)
153 sprintf(tmp_name
, "%s%s%s", "/tmp/", tname
, "XXXXXX");
156 if ((fd_out
= _fopen(tmp_name
, "a+")) == NULL
) {
161 while (getmntline(line
, fd_in
) != -1) {
162 if (strcmp(fname
, "/etc/mnttab") == 0) {
163 if (putmline(line
, fd_out
) == -1) {
168 } else { /* processing vfstab */
169 if (putfline(line
, fd_out
) == -1) {
181 fd
= _syscall(SYS_openat
, AT_FDCWD
, tmp_name
, O_RDONLY
);
183 if (fd
== -1 || unlink(tmp_name
) == -1)
195 getmntline(char *lp
, FILE *fp
)
200 while ((lp
= fgets(lp
, MNT_LINE_MAX
, fp
)) != NULL
) {
201 if (strlen(lp
) == MNT_LINE_MAX
-1 && lp
[MNT_LINE_MAX
-2] != '\n')
203 for (cp
= lp
; *cp
== ' ' || *cp
== '\t'; cp
++)
205 if (*cp
!= '#' && *cp
!= '\n')
212 putmline(char *line
, FILE *fp
)
216 char *devnumstr
= 0; /* the device number, in (hex) ascii */
217 char *remainder
; /* remainder of mnt_opts string, after devnum */
218 unsigned long devnum
;
220 GETTOK(mnt
.mnt_fsname
, line
);
221 GETTOK(mnt
.mnt_dir
, NULL
);
222 GETTOK(mnt
.mnt_type
, NULL
);
223 GETTOK(mnt
.mnt_opts
, NULL
);
228 if (strtok(NULL
, sepstr
) != NULL
)
230 if (strcmp(mnt
.mnt_type
, "ufs") == 0) {
231 mnt
.mnt_type
= "4.2";
235 * the device number, if present, follows the '='
236 * in the mnt_opts string.
239 if (mnt
.mnt_opts
!= NULL
)
240 devnumstr
= (char *)strchr(mnt
.mnt_opts
, '=');
243 /* no device number on this line */
244 fprintf(fp
, "%s %s %s %s %d %d\n",
245 mnt
.mnt_fsname
, mnt
.mnt_dir
, mnt
.mnt_type
,
246 mnt
.mnt_opts
, mnt
.mnt_freq
, mnt
.mnt_passno
);
248 /* found the device number, convert it to 4.x format */
249 devnum
= strtol(&devnumstr
[1], (char **)NULL
, 16);
250 remainder
= (char *)strchr(&devnumstr
[1], ' ');
251 devnumstr
[1] = 0; /* null terminate mnt_opts after '=' */
252 devnum
= cmpdev(devnum
);
254 fprintf(fp
, "%s %s %s %s%4x%s %d %d\n",
255 mnt
.mnt_fsname
, mnt
.mnt_dir
, mnt
.mnt_type
,
256 mnt
.mnt_opts
, devnum
, remainder
? remainder
: "",
257 mnt
.mnt_freq
, mnt
.mnt_passno
);
264 putfline(char *line
, FILE *fp
)
269 GETTOK(mnt
.mnt_fsname
, line
);
271 GETTOK(mnt
.mnt_dir
, NULL
);
272 if (mnt
.mnt_dir
== NULL
&& strcmp(mnt
.mnt_fsname
, "/dev/root") == 0)
274 GETTOK(mnt
.mnt_type
, NULL
);
277 GETTOK(mnt
.mnt_opts
, NULL
);
278 if (mnt
.mnt_opts
== NULL
)
283 if (strtok(NULL
, sepstr
) != NULL
)
285 if (strcmp(mnt
.mnt_type
, "ufs") == 0) {
286 mnt
.mnt_type
= "4.2";
289 fprintf(fp
, "%s %s %s %s %d %d\n",
290 mnt
.mnt_fsname
, mnt
.mnt_dir
, mnt
.mnt_type
,
291 mnt
.mnt_opts
, mnt
.mnt_freq
, mnt
.mnt_passno
);
297 _fopen(char *file
, char *mode
)
299 extern FILE *_findiop();
306 if (iop
== NULL
|| file
== NULL
|| file
[0] == '\0')
308 plus
= (mode
[1] == '+');
311 oflag
= (plus
? O_RDWR
: O_WRONLY
) | N_O_TRUNC
| N_O_CREAT
;
314 oflag
= (plus
? O_RDWR
: O_WRONLY
) | N_O_CREAT
;
317 oflag
= plus
? O_RDWR
: O_RDONLY
;
322 if ((fd
= _syscall(SYS_openat
, AT_FDCWD
, file
, oflag
, 0666)) < 0)
326 iop
->_flag
= plus
? _IORW
: (mode
[0] == 'r') ? _IOREAD
: _IOWRT
;
327 if (mode
[0] == 'a') {
328 if ((lseek(fd
, 0L, 2)) < 0) {
333 iop
->_base
= iop
->_ptr
= NULL
;
343 char tmp_name
[] = "/tmp/printcap.XXXXXX";
346 struct dirent
*entry
;
349 if ((fd
= _fopen(tmp_name
, "a+")) == NULL
)
351 fprintf(fd
, "# Derived from lp(1) configuration information for BCP\n");
353 if ((printerDir
= opendir(PRINTER_DIR
)) != NULL
) {
354 while ((entry
= readdir(printerDir
)) != NULL
)
355 if (entry
->d_name
[0] != '.')
356 getPrinterInfo(entry
->d_name
, fd
);
357 closedir(printerDir
);
361 tmp_file
= _syscall(SYS_openat
, AT_FDCWD
, tmp_name
, O_RDONLY
);
362 if (tmp_file
== -1 || unlink(tmp_name
) == -1)
369 getPrinterInfo(char *printerName
, FILE *fd
)
378 fullPath
= (char *)malloc(strlen(PRINTER_DIR
) + strlen(printerName
) +
379 strlen(PRINTER_CONFIG_FILE
) + 1);
380 strcpy(fullPath
, PRINTER_DIR
);
381 strcat(fullPath
, printerName
);
382 strcat(fullPath
, PRINTER_CONFIG_FILE
);
384 if ((config_fd
= _syscall(SYS_openat
, AT_FDCWD
, fullPath
, O_RDONLY
))
389 if ((fstat(config_fd
, &buf
)) != 0 ||
390 (str
= (char *)malloc(buf
.st_size
+ 2)) == NULL
) {
395 if ((read(config_fd
, str
, buf
.st_size
)) != buf
.st_size
) {
401 p
= &str
[buf
.st_size
];
405 fprintf(fd
, "%s:", printerName
);
406 if ((p
= (char *)_strstr(str
, "Remote")) != NULL
) {
408 p
= (char *)strchr(p
, ' ') + 1;
409 c
= (char *)strchr(p
, '\n');
411 fprintf(fd
, "lp=:rm=%s:rp=%s:\n", p
, printerName
);
412 } else if ((p
= (char *)_strstr(str
, "Device")) != NULL
) {
414 p
= (char *)strchr(p
, ' ') + 1;
415 c
= (char *)strchr(p
, '\n');
417 fprintf(fd
, "lp=%s:\n", p
);