1
0
Files
irix-657m-src/eoe/cmd/macplang/macplanged.c
2022-09-29 17:59:04 +03:00

285 lines
7.6 KiB
C

/**************************************************************************
* *
* Copyright (C) 1990, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/*
* #ident "$Revision: 1.2 $"
*
* macplanged - directly edit an existing Plan G database.
*
*
* macplanged label path
*/
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <strings.h>
#include <mls.h>
#define BUFFERS 512
main(argc, argv)
int argc;
char *argv[];
{
eag_mac_index_t *indexs; /* The in-core index file */
eag_mac_index_t element; /* Value of the index file entry */
char *path; /* File to update */
char *cp;
char index_file[PATH_MAX]; /* Name of the index file */
char index_tmp_file[PATH_MAX]; /* Name of the index tmp file */
char index_old_file[PATH_MAX]; /* Name of the index old file */
char label_file[PATH_MAX]; /* Name of the label file */
FILE *index_fp; /* the index file */
FILE *index_tmp_fp; /* the index tmp file */
FILE *label_fp; /* the label file */
FILE *fp; /* For popen of df(1) */
struct stat statbuf; /* return from stat(2) */
char buffer[BUFFERS]; /* Read buffer */
int inode; /* inode # */
mac_label *lp; /* Binary value of label */
int i;
if (argc != 3) {
fprintf(stderr, "macplanged: Usage: macplanged label path\n");
exit(1);
}
if ((lp = mac_strtolabel(argv[1])) == NULL) {
fprintf(stderr, "macplanged: label is invalid.\n");
exit(1);
}
path = argv[2];
/*
* Get the inode number of the file.
*/
if (lstat(path, &statbuf) == -1) {
perror("macplanged: stat");
exit(1);
}
inode = statbuf.st_ino;
/*
* Invoke df(1) as the most convenient way to get the name of
* the file system upon which the file resides.
* NOTE: This code assumes an unchanging format of output from
* df(1). There may come a time when this assumption turns out
* to be inappropriate.
*/
sprintf(buffer, "/bin/df %s", path);
if ((fp = popen(buffer, "r")) == NULL) {
perror("macplanged: popen");
exit(1);
}
/*
* Toss aside the first line, as it's the header.
*/
if (fgets(buffer, BUFFERS, fp) == NULL) {
perror("macplanged: initial fgets");
exit(1);
}
/*
* There'd better be a second line.
*/
if (fgets(buffer, BUFFERS, fp) == NULL) {
perror("macplanged: initial fgets");
exit(1);
}
pclose(fp);
/*
* If the file system is mounted by NFS then we don't want to do
* this.
*/
if ((cp = strtok(buffer, "\n\t ")) == NULL) {
fprintf(stderr, "macplanged: output from df mangled\n");
exit(1);
}
if ((cp = strtok(NULL, "\n\t ")) == NULL) {
fprintf(stderr, "macplanged: output from df mangled\n");
exit(1);
}
if (strncmp(cp, "efs", 3) != 0) {
fprintf(stderr,
"macplanged: Will only update EFS file systems\n");
exit(1);
}
/*
* Skip 'blocks' field
*/
if ((cp = strtok(NULL, "\n\t ")) == NULL) {
fprintf(stderr, "macplanged: output from df mangled\n");
exit(1);
}
/*
* Skip 'use' field
*/
if ((cp = strtok(NULL, "\n\t ")) == NULL) {
fprintf(stderr, "macplanged: output from df mangled\n");
exit(1);
}
/*
* Skip 'avail' field
*/
if ((cp = strtok(NULL, "\n\t ")) == NULL) {
fprintf(stderr, "macplanged: output from df mangled\n");
exit(1);
}
/*
* Skip '%use' field
*/
if ((cp = strtok(NULL, "\n\t ")) == NULL) {
fprintf(stderr, "macplanged: output from df mangled\n");
exit(1);
}
/*
* Get to 'Mounted on' field
*/
if ((cp = strtok(NULL, "\n\t ")) == NULL) {
fprintf(stderr, "macplanged: output from df mangled\n");
exit(1);
}
/*
* Open the index file and a temporary to copy it into.
*/
sprintf(label_file, "%s/%s", cp, EAG_MAC_LABEL);
sprintf(index_file, "%s/%s", cp, EAG_MAC_INDEX);
sprintf(index_tmp_file, "%s/%s.TMP", cp, EAG_MAC_INDEX);
sprintf(index_old_file, "%s/%s.OLD", cp, EAG_MAC_INDEX);
if ((index_fp = fopen(index_file, "r")) == NULL) {
perror("macplanged: opening index file");
exit(1);
}
if ((index_tmp_fp = fopen(index_tmp_file, "w")) == NULL) {
perror("macplanged: opening index tmp file");
exit(1);
}
/*
* Copy the preceeding parts of the index file.
*/
for (i = 0; i < inode; i++) {
if (fread(&element, sizeof(element), 1, index_fp) < 0) {
fprintf(stderr, "macplanged: premature EOF.\n");
exit(1);
}
if (fwrite(&element,sizeof(element),1,index_tmp_fp) < 0) {
fprintf(stderr, "macplanged: Write failure.\n");
exit(1);
}
}
/*
* Read in the current value for this record.
*/
if (fread(&element, sizeof(element), 1, index_fp) < 0) {
fprintf(stderr, "macplanged: premature EOF.\n");
exit(1);
}
if ((i = mac_size(lp)) <= 2 * sizeof(int)) {
/*
* If the new value fits in a direct entry do so.
*/
bcopy(lp, &element, i);
element.emi_flags = EAG_MAC_DIRECT;
}
else {
element.emi_size = i;
element.emi_flags = 0;
element.emi_index = -1;
/*
* Since the new value does not fit in a direct entry
* look for its value in the labels file, adding it if
* it's not there.
*/
if ((label_fp = fopen(label_file, "r")) == NULL) {
perror("macplanged: opening label file");
exit(1);
}
while (fread(&i, sizeof(int), 1, label_fp) > 0) {
element.emi_index = ftell(label_fp) - sizeof(int);
if (i > BUFFERS) {
fprintf(stderr,
"macplanged: oversized label entry.\n");
exit(1);
}
if (fread(buffer, i, 1, label_fp) < 0) {
perror("macplanged: reading label file");
exit(1);
}
/*
* If the label is found then store the index and
* exit the loop.
*/
if (i != element.emi_size ||
bcmp(lp, buffer, element.emi_size) != 0)
element.emi_index = -1;
}
/*
* If the label is not already in the labels file append it.
*/
if (element.emi_index == -1) {
element.emi_index = ftell(label_fp);
fclose(label_fp);
if ((label_fp = fopen(label_file, "a")) == NULL) {
perror("macplanged: appending label file");
exit(1);
}
if (fwrite(&element.emi_size, sizeof(int), 1,
label_fp) < 0) {
perror("macplanged: Append failure");
exit(1);
}
if (fwrite(lp, element.emi_size, 1, label_fp) < 0) {
perror("macplanged: Append failure");
exit(1);
}
}
fclose(label_fp);
}
if (fwrite(&element,sizeof(element),1,index_tmp_fp) < 0) {
fprintf(stderr, "macplanged: Write failure.\n");
exit(1);
}
/*
* Copy the subsequent parts of the index file.
*/
while (fread(&element, sizeof(element), 1, index_fp) > 0) {
if (fwrite(&element,sizeof(element),1,index_tmp_fp) < 0) {
fprintf(stderr, "macplanged: Write failure.\n");
exit(1);
}
}
if (fclose(index_fp) < 0) {
perror("macplanged: closing index file");
exit(1);
}
if (fclose(index_tmp_fp) < 0) {
perror("macplanged: closing index tmp file");
exit(1);
}
/*
* Move the old file away and the new in.
*/
if (rename(index_file, index_old_file) < 0) {
perror("macplanged: saving old index file");
exit(1);
}
if (rename(index_tmp_file, index_file) < 0) {
perror("macplanged: establishing new index file");
exit(1);
}
exit(0);
}