395 lines
8.7 KiB
C
Executable File
395 lines
8.7 KiB
C
Executable File
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <strings.h>
|
|
#include <mntent.h>
|
|
#include <syscall.h>
|
|
#include <sys/param.h>
|
|
#include <sys/sysmacros.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <dirent.h>
|
|
#include "s5sysmacros.h"
|
|
|
|
#define PRINTER_DIR "/etc/lp/printers/"
|
|
#define PRINTER_CONFIG_FILE "/configuration"
|
|
#define MNT_LINE_MAX 1024
|
|
|
|
#define GETTOK(xx, ll) \
|
|
if ((xx = strtok(ll, sepstr)) == NULL) \
|
|
return (-1); \
|
|
if (strcmp(xx, dash) == 0) \
|
|
xx = NULL
|
|
|
|
char *mktemp();
|
|
char *strtok();
|
|
static void getPrinterInfo(char*, FILE*);
|
|
static char sepstr[] = " \t\n";
|
|
static char dash[] = "-";
|
|
|
|
/* SVR4/SunOS 5.0 equivalent modes */
|
|
#define N_O_NDELAY 0x04
|
|
#define N_O_SYNC 0x10
|
|
#define N_O_NONBLOCK 0x80
|
|
#define N_O_CREAT 0x100
|
|
#define N_O_TRUNC 0x200
|
|
#define N_O_EXCL 0x400
|
|
|
|
/* Mask corresponding to the bits above in SunOS 4.x */
|
|
#define FLAGS_MASK (O_SYNC|O_NONBLOCK|O_CREAT|O_TRUNC|O_EXCL \
|
|
|_FNDELAY|_FNBIO)
|
|
|
|
|
|
open_com(path, flags, mode)
|
|
char *path;
|
|
int flags;
|
|
int mode;
|
|
{
|
|
int fd, fd2, pathl, inspt, ret = 0;
|
|
int nflags = flags;
|
|
char loc[] = "/lib/locale";
|
|
char *loct = NULL;
|
|
|
|
if (flags & FLAGS_MASK) {
|
|
nflags = flags & ~FLAGS_MASK;
|
|
if (flags & O_SYNC)
|
|
nflags |= N_O_SYNC;
|
|
if (flags & (_FNDELAY|O_NONBLOCK)) {
|
|
nflags |= N_O_NONBLOCK;
|
|
}
|
|
if (flags & O_CREAT)
|
|
nflags |= N_O_CREAT;
|
|
if (flags & O_TRUNC)
|
|
nflags |= N_O_TRUNC;
|
|
if (flags & O_EXCL)
|
|
nflags |= N_O_EXCL;
|
|
if (flags & _FNBIO)
|
|
nflags |= N_O_NDELAY;
|
|
}
|
|
|
|
/* change path from ..../lib/locale/.... to ..../lib/oldlocale/.... XXX */
|
|
|
|
if ((loct = (char*)_strstr(path, loc)) != NULL) { /* /lib/locale ? */
|
|
char locbuf[MAXPATHLEN+100]; /* to hold new locale path */
|
|
|
|
pathl = strlen(path);
|
|
inspt = pathl - strlen(loct) + 5; /* pos to add "old" */
|
|
strncpy(locbuf, path, inspt); /* copy in path upto lib */
|
|
locbuf[inspt] = '\0'; /* make it a string */
|
|
strcat(locbuf, "old"); /* add "old" */
|
|
strcat(locbuf, loct+5); /* add remainer of path */
|
|
return (_syscall(SYS_open, locbuf, nflags, mode));
|
|
}
|
|
|
|
if (strcmp(path, "/etc/mtab") == 0) {
|
|
return (open_mnt("/etc/mnttab", "mtab", nflags, mode));
|
|
} else
|
|
if (strcmp(path, "/etc/fstab") == 0) {
|
|
return (open_mnt("/etc/vfstab", "fstab", nflags, mode));
|
|
} else
|
|
if (strcmp(path, "/etc/printcap") == 0) {
|
|
if ((fd = _syscall(SYS_open, path, nflags, mode)) != -1)
|
|
return (fd);
|
|
return (open_printcap());
|
|
} else
|
|
if (strcmp(path, "/etc/utmp") == 0 ||
|
|
strcmp(path, "/var/adm/wtmp") == 0) {
|
|
char buf[MAXPATHLEN+100];
|
|
|
|
if ((fd = _syscall(SYS_open, path, nflags, mode)) == -1)
|
|
return (-1);
|
|
strcpy(buf, path);
|
|
strcat(buf, "x");
|
|
if ((fd2 = _syscall(SYS_open, buf, nflags, mode)) == -1) {
|
|
_syscall(SYS_close, fd);
|
|
return (-1);
|
|
}
|
|
fd_add(fd, fd2);
|
|
return (fd);
|
|
} else
|
|
return (_syscall(SYS_open, path, nflags, mode));
|
|
}
|
|
|
|
open_mnt(fname, tname, flags, mode)
|
|
char *fname, *tname;
|
|
int flags;
|
|
int mode;
|
|
{
|
|
FILE *fd_in, *fd_out;
|
|
FILE *_fopen();
|
|
char tmp_name[64];
|
|
char line[MNT_LINE_MAX];
|
|
int fd;
|
|
|
|
if ((fd_in = _fopen(fname, "r")) == NULL)
|
|
return (-1);
|
|
|
|
sprintf(tmp_name, "%s%s%s", "/tmp/", tname, "XXXXXX");
|
|
mktemp(tmp_name);
|
|
|
|
if ((fd_out = _fopen(tmp_name, "a+")) == NULL) {
|
|
fclose(fd_in);
|
|
return (-1);
|
|
}
|
|
|
|
while (getmntline(line, fd_in) != -1) {
|
|
if (strcmp(fname, "/etc/mnttab") == 0) {
|
|
if (putmline(line, fd_out) == -1) {
|
|
fclose(fd_in);
|
|
fclose(fd_out);
|
|
return (-1);
|
|
}
|
|
} else /* processing vfstab */
|
|
if (putfline(line, fd_out) == -1) {
|
|
fclose(fd_in);
|
|
fclose(fd_out);
|
|
return (-1);
|
|
}
|
|
}
|
|
|
|
if (feof(fd_in)) {
|
|
fclose(fd_in);
|
|
fclose(fd_out);
|
|
|
|
fd = _syscall(SYS_open, tmp_name, O_RDONLY);
|
|
|
|
if (fd == -1 || unlink(tmp_name) == -1)
|
|
return (-1);
|
|
|
|
return (fd);
|
|
} else {
|
|
fclose(fd_in);
|
|
fclose(fd_out);
|
|
return (-1);
|
|
}
|
|
}
|
|
|
|
|
|
int getmntline(lp, fp)
|
|
char *lp;
|
|
FILE *fp;
|
|
{
|
|
int ret;
|
|
char *cp;
|
|
|
|
while ((lp = fgets(lp, MNT_LINE_MAX, fp)) != NULL) {
|
|
if (strlen(lp) == MNT_LINE_MAX-1 && lp[MNT_LINE_MAX-2] != '\n')
|
|
return (-1);
|
|
for (cp = lp; *cp == ' ' || *cp == '\t'; cp++)
|
|
;
|
|
if (*cp != '#' && *cp != '\n')
|
|
return (0);
|
|
}
|
|
return (-1);
|
|
}
|
|
|
|
putmline(line, fp)
|
|
char *line;
|
|
FILE *fp;
|
|
{
|
|
struct mntent mnt;
|
|
char *buf;
|
|
char *devnumstr; /* the device number, in (hex) ascii */
|
|
char *remainder; /* remainder of mnt_opts string, after devnum */
|
|
unsigned long devnum;
|
|
|
|
GETTOK(mnt.mnt_fsname, line);
|
|
GETTOK(mnt.mnt_dir, NULL);
|
|
GETTOK(mnt.mnt_type, NULL);
|
|
GETTOK(mnt.mnt_opts, NULL);
|
|
GETTOK(buf, NULL);
|
|
mnt.mnt_freq = 0;
|
|
mnt.mnt_passno = 0;
|
|
|
|
if (strtok(NULL, sepstr) != NULL)
|
|
return (-1);
|
|
if (strcmp(mnt.mnt_type, "ufs") == 0) {
|
|
mnt.mnt_type = "4.2";
|
|
}
|
|
|
|
/*
|
|
* the device number, if present, follows the '='
|
|
* in the mnt_opts string.
|
|
*/
|
|
|
|
devnumstr = (char *)strchr(mnt.mnt_opts, '=');
|
|
if (!devnumstr) {
|
|
/* no device number on this line */
|
|
fprintf(fp, "%s %s %s %s %d %d\n",
|
|
mnt.mnt_fsname, mnt.mnt_dir, mnt.mnt_type,
|
|
mnt.mnt_opts, mnt.mnt_freq, mnt.mnt_passno);
|
|
} else {
|
|
/* found the device number, convert it to 4.x format */
|
|
devnum = strtol(&devnumstr[1], (char **) NULL, 16);
|
|
remainder = (char *)strchr(&devnumstr[1], ' ');
|
|
devnumstr[1] = 0; /* null terminate mnt_opts after '=' */
|
|
devnum = cmpdev(devnum);
|
|
|
|
fprintf(fp, "%s %s %s %s%4x%s %d %d\n",
|
|
mnt.mnt_fsname, mnt.mnt_dir, mnt.mnt_type,
|
|
mnt.mnt_opts, devnum, remainder ? remainder : "",
|
|
mnt.mnt_freq, mnt.mnt_passno);
|
|
}
|
|
}
|
|
|
|
putfline(line, fp)
|
|
char *line;
|
|
FILE *fp;
|
|
{
|
|
struct mntent mnt;
|
|
char *buf;
|
|
|
|
GETTOK(mnt.mnt_fsname, line);
|
|
GETTOK(buf, NULL);
|
|
GETTOK(mnt.mnt_dir, NULL);
|
|
if (mnt.mnt_dir == NULL && strcmp(mnt.mnt_fsname, "/dev/root") == 0)
|
|
mnt.mnt_dir = "/";
|
|
GETTOK(mnt.mnt_type, NULL);
|
|
GETTOK(buf, NULL);
|
|
GETTOK(buf, NULL);
|
|
GETTOK(mnt.mnt_opts, NULL);
|
|
if (mnt.mnt_opts == NULL)
|
|
mnt.mnt_opts = "rw";
|
|
mnt.mnt_freq = 0;
|
|
mnt.mnt_passno = 0;
|
|
|
|
if (strtok(NULL, sepstr) != NULL)
|
|
return (-1);
|
|
if (strcmp(mnt.mnt_type, "ufs") == 0) {
|
|
mnt.mnt_type = "4.2";
|
|
}
|
|
|
|
fprintf(fp, "%s %s %s %s %d %d\n",
|
|
mnt.mnt_fsname, mnt.mnt_dir, mnt.mnt_type,
|
|
mnt.mnt_opts, mnt.mnt_freq, mnt.mnt_passno);
|
|
}
|
|
|
|
|
|
/*
|
|
static FILE *_fopen(file, mode)
|
|
*/
|
|
FILE *_fopen(file, mode)
|
|
char *file, *mode;
|
|
{
|
|
extern FILE *_findiop();
|
|
FILE *iop;
|
|
|
|
register int plus, oflag, fd;
|
|
|
|
iop = _findiop();
|
|
|
|
if (iop == NULL || file == NULL || file[0] == '\0')
|
|
return (NULL);
|
|
plus = (mode[1] == '+');
|
|
switch (mode[0]) {
|
|
case 'w':
|
|
oflag = (plus ? O_RDWR : O_WRONLY) | N_O_TRUNC | N_O_CREAT;
|
|
break;
|
|
case 'a':
|
|
oflag = (plus ? O_RDWR : O_WRONLY) | N_O_CREAT;
|
|
break;
|
|
case 'r':
|
|
oflag = plus ? O_RDWR : O_RDONLY;
|
|
break;
|
|
default:
|
|
return (NULL);
|
|
}
|
|
if ((fd = _syscall(SYS_open, file, oflag, 0666)) < 0)
|
|
return (NULL);
|
|
iop->_cnt = 0;
|
|
iop->_file = fd;
|
|
iop->_flag = plus ? _IORW : (mode[0] == 'r') ? _IOREAD : _IOWRT;
|
|
if (mode[0] == 'a') {
|
|
if ((lseek(fd, 0L, 2)) < 0) {
|
|
(void) close(fd);
|
|
return (NULL);
|
|
}
|
|
}
|
|
iop->_base = iop->_ptr = NULL;
|
|
iop->_bufsiz = 0;
|
|
return (iop);
|
|
}
|
|
|
|
static int
|
|
open_printcap()
|
|
{
|
|
FILE *fd;
|
|
FILE *_fopen();
|
|
char *tmp_name = "/tmp/printcap.XXXXXX";
|
|
int tmp_file;
|
|
DIR *printerDir;
|
|
struct dirent *entry;
|
|
|
|
mktemp(tmp_name);
|
|
if ((fd = _fopen(tmp_name, "a+")) == NULL)
|
|
return (-1);
|
|
fprintf(fd, "# Derived from lp(1) configuration information for BCP\n");
|
|
|
|
if ((printerDir = opendir(PRINTER_DIR)) != NULL) {
|
|
while ((entry = readdir(printerDir)) != NULL)
|
|
if (entry->d_name[0] != '.')
|
|
getPrinterInfo(entry->d_name, fd);
|
|
closedir(printerDir);
|
|
}
|
|
fclose(fd);
|
|
|
|
tmp_file = _syscall(SYS_open, tmp_name, O_RDONLY);
|
|
if (tmp_file == -1 || unlink(tmp_name) == -1)
|
|
return (-1);
|
|
|
|
return (tmp_file);
|
|
}
|
|
|
|
|
|
static void
|
|
getPrinterInfo(char *printerName, FILE *fd)
|
|
{
|
|
char *fullPath;
|
|
char *str;
|
|
char *p;
|
|
char *c;
|
|
struct stat buf;
|
|
int config_fd;
|
|
|
|
fullPath = (char*)malloc(strlen(PRINTER_DIR) + strlen(printerName) +
|
|
strlen(PRINTER_CONFIG_FILE) + 1);
|
|
strcpy(fullPath, PRINTER_DIR);
|
|
strcat(fullPath, printerName);
|
|
strcat(fullPath, PRINTER_CONFIG_FILE);
|
|
|
|
if ((config_fd = _syscall(SYS_open, fullPath, O_RDONLY)) == -1) {
|
|
free (fullPath);
|
|
return;
|
|
}
|
|
if ((fstat(config_fd, &buf)) != 0 ||
|
|
(str = (char*)malloc(buf.st_size + 2)) == NULL) {
|
|
free (fullPath);
|
|
close(config_fd);
|
|
return;
|
|
}
|
|
if ((read(config_fd, str, buf.st_size)) != buf.st_size) {
|
|
free (fullPath);
|
|
free(str);
|
|
close(config_fd);
|
|
return;
|
|
}
|
|
p = &str[buf.st_size];
|
|
p[0] = '\n';
|
|
p[1] = '\0';
|
|
|
|
fprintf(fd, "%s:", printerName);
|
|
if ((p = (char*)_strstr(str, "Remote")) != NULL) { /* remote printer */
|
|
p = (char*)strchr(p, ' ') + 1;
|
|
c = (char*)strchr(p, '\n');
|
|
*c = '\0';
|
|
fprintf(fd, "lp=:rm=%s:rp=%s:\n", p, printerName);
|
|
} else if ((p = (char*)_strstr(str, "Device")) != NULL) { /* local printer */
|
|
p = (char*)strchr(p, ' ') + 1;
|
|
c = (char*)strchr(p, '\n');
|
|
*c = '\0';
|
|
fprintf(fd, "lp=%s:\n", p);
|
|
}
|
|
free(fullPath);
|
|
free(str);
|
|
close(config_fd);
|
|
}
|