Files
Arquivotheca.Solaris-2.5/lib/libbc/libc/sys/common/_open.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

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);
}