Files
pcas/src/util/apCreateShadow.c
1994-01-14 08:27:27 +00:00

390 lines
12 KiB
C

/*
* apCreateShadow.c
* todo - if symbolic link is relative
* - it should be the same as the one in the source area
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#define SAME 0
static void Usage();
static void procDirEntries();
static void createLink();
static void procLink();
static void processFile();
static void dirwalk();
static void startFromHere();
static void init_setup();
int errno;
static struct stat stbuf;
static char buffer[MAXPATHLEN];
static char dest_base[MAXPATHLEN]; /* dest base (root of shadow node) */
static char src_base[MAXPATHLEN]; /* current source descend root node */
static char dpath[MAXPATHLEN]; /* dest/subdir... */
static char spath[MAXPATHLEN]; /* src/subdir... */
static char progName[30]; /* program name */
static char sys_top[MAXPATHLEN]; /* root node */
static char topAppl[MAXPATHLEN];/* pathname of master appLoc file */
/****************************************************************************
MAIN PROGRAM
This program creates an application developers set of shadow nodes
It must be invoked with a full path name so that the official
application area is known.
****************************************************************************/
main(argc, argv)
int argc;
char **argv;
{
/*
* intial setup
*/
init_setup(argc, argv);
if (chdir(sys_top)!=0) {
fprintf(stderr, "%s: Can't chdir\n", progName);
exit(1);
}
startFromHere();
fprintf(stderr, "apCreateShadow %s\n", "completed");
return (0);
}
/****************************************************************************
PROCLINK
****************************************************************************/
static void
procLink(name)
char *name;
{
char buff[MAXPATHLEN];
int num_chars;
if ((num_chars = readlink(name, buff, MAXPATHLEN)) < 0) {
fprintf(stderr, "procLink: FATAL ERROR - errno=%d name=%s\n", errno, name);
exit(1);
}
buff[num_chars] = NULL;
if ((buff[0] == '/') || ((buff[0] == '.') && (buff[1] == '/'))) {
strcpy(spath, src_base);
strcat(spath, "/");
strcat(spath, name);
} else {
strcpy(spath, buff);
}
strcpy(dpath, dest_base);
strcat(dpath, "/");
strcat(dpath, name);
createLink();
}
/****************************************************************************
CREATELINK
****************************************************************************/
static void
createLink()
{
/*
A symbolic link name2 is created to name1 (name2 is the name
of the file created, name1 is the string used in creating
the symbolic link). Either name may be an arbitrary path
name; the files need not be on the same file system.
*/
if ( access(dpath,R_OK|F_OK)) {
if ((symlink(spath, dpath)) != 0) {
printf("\n####################################################\n");
printf("createLink: symlink failure: errno=%d\nspath=%s\n\tdpath=%s\n"
,errno, spath, dpath);
printf("####################################################\n");
}
}
}
/****************************************************************************
DIRWALK applies a function to each file in a directory
****************************************************************************/
static void
dirwalk(dir, dbflag, fcn)
char *dir;
int dbflag; /* in database directory flag*/
void (*fcn) ();
{
char name[MAXNAMLEN];
struct dirent *dp;
DIR *dfd;
if ((dfd = opendir(dir)) == NULL) {
fprintf(stderr, "dirwalk: can't open %s\n", dir);
exit(1);
}
while ((dp = readdir(dfd)) != NULL) {
if (strcmp(dp->d_name, ".") == 0
|| strcmp(dp->d_name, "..") == 0)
continue; /* skip self and parent */
if (strlen(dir) + strlen(dp->d_name) + 2 > sizeof(name))
fprintf(stderr, "dirwalk: name %s/%s too long\n",
dir, dp->d_name);
else {
sprintf(name, "%s/%s", dir, dp->d_name);
(*fcn) (name, dir, dbflag);
}
}
closedir(dfd);
}
static void
Usage()
{
printf("\nUsage:\t%s <root of application system area>\n", progName);
}
/****************************************************************************
PROCESSFILE
create a soft link and return
****************************************************************************/
static void
processFile(name, indbdirflag)
char *name; /* regular file */
int indbdirflag;/* in database directory flag */
{
char *ptr;
char cmd[2 * MAXNAMLEN];
strcpy(spath, src_base);
strcat(spath, "/");
strcat(spath, name);
strcpy(dpath, dest_base);
strcat(dpath, "/");
strcat(dpath, name);
if ((ptr = (char *) strstr(name, "Db.")) != NULL
&& indbdirflag != 0) {
/* only link in <*>Db.database files */
if ((ptr = (char *) strstr(name, "Db.database")) != NULL) {
createLink();
} else {
return;
}
} else {
createLink();
}
return;
}
/****************************************************************************
INIT_SETUP
****************************************************************************/
static void
init_setup(argc, argv)
int argc;
char **argv;
{
char *ptr;
int len;
FILE *origin_fp;
char Xdest_base[MAXPATHLEN];
char Xsrc_base[MAXPATHLEN];
ptr = (char *) strrchr(argv[0], '/');
if (ptr == 0) {
strcpy(progName, argv[0]);
} else {
strcpy(progName, ptr + 1);
}
if (argc != 2) {
printf("####################################################\n");
Usage();
if ((access(".applShadowOrgin",R_OK|F_OK) == 0)) {
system("/usr/5bin/echo \"previous invocation:\n\\tapCreateShadow \\c\";cat .applShadowOrgin");
}
printf("####################################################\n");
exit(1);
}
if (*argv[1] != '/') {
printf("####################################################\n");
printf("%s: ERROR - arg#1 must be a full pathname\n", progName);
Usage();
printf("####################################################\n");
exit(1);
}
/* check to see if path points to app system area - file .topAppl exists*/
/* application base is argv[1] */
len = strlen(argv[1]);
strncpy(sys_top, argv[1], len);
sys_top[len] = NULL;
strcpy(topAppl, sys_top);
strcat(topAppl, "/.topAppl");
if ((stat(topAppl, &stbuf)) != 0) {
fprintf(stderr, "####################################################\n");
fprintf(stderr, "%s: Can't stat file: %s\n", progName, topAppl);
fprintf(stderr, "####################################################\n");
Usage();
exit(1);
}
/* get shadow base */
if ((getcwd(dest_base, 78)) == NULL) {
fprintf(stderr, "getcwd failed\n");
exit(1);
}
strcpy(src_base, sys_top);
/* if dest_base is substring of src_base - recursion occurs */
strcpy(Xdest_base, dest_base);
strcat(Xdest_base, "/");
strcpy(Xsrc_base, src_base);
strcat(Xsrc_base, "/");
if ((strstr(Xdest_base, Xsrc_base)) != NULL) { /* error */
fprintf(stderr, "####################################################\n");
fprintf(stderr, "%s: You can't run this tool in an application system area!\n", progName);
fprintf(stderr, "####################################################\n");
exit(1);
}
/* if .applShadow doesn't exist - require touch .applShadow */
if ((stat("./.applShadow", &stbuf)) != 0) {
fprintf(stderr, "\n");
fprintf(stderr, "####################################################\n");
fprintf(stderr, "%s: Can't stat file: './applShadow'\n", progName);
fprintf(stderr, "####################################################\n");
fprintf(stderr, "If this is NOT the root of your application shadow directory,\n");
fprintf(stderr, "then please cd to the appropriate place and try again.\n");
fprintf(stderr, "If this IS the root your shadow directory, then create .applShadow\n");
fprintf(stderr, "with the following command and then run %s again.\n", progName);
fprintf(stderr, " %%\n touch .applShadow\n");
fprintf(stderr, "####################################################\n");
exit(1);
}
/*********************** create/check an invocation marker *******************/
/*rz*/
if ((stat("./.applShadowOrgin", &stbuf)) != 0) {
if ((origin_fp = fopen("./.applShadowOrgin", "w")) == NULL) {
fprintf(stderr, "%s: can't fopen %s in dest_base area\n",
progName, ".applShadowOrgin");
exit(1);
}
fprintf(origin_fp, "%s\n", sys_top);
} else {
if ((origin_fp = fopen("./.applShadowOrgin", "r")) == NULL) {
fprintf(stderr, "%s: can't fopen %s in dest_base area\n",
progName, ".applShadowOrgin");
exit(1);
}
/* compare sys_top with buffer */
while ((fgets(buffer, sizeof(buffer) + 2, origin_fp)) != NULL) {
len = strlen(buffer);
/* remove the N/L from input line */
if (buffer[len - 1] == '\n') {
buffer[len - 1] = 0;
}
if ((strcmp(buffer, sys_top)) != SAME) {
fprintf(stderr, "%s: FATAL ERROR - Illegal invocation\n", progName);
fprintf(stderr,
"Your last system area was %s\n", buffer);
fprintf(stderr,
"Your new (arg1) system area is %s\n", sys_top);
exit(1);
}
}
}
fclose(origin_fp);
}
/*********************************************/
static void
startFromHere()
{
char *dir = ".";
char name[MAXNAMLEN];
struct dirent *dp;
DIR *dfd;
int localdbflag=0; /* in database directory flag*/
if ((dfd = opendir(dir)) == NULL) {
fprintf(stderr, "startFromHere: can't open %s\n", dir);
exit(1);
}
while ((dp = readdir(dfd)) != NULL) {
if (strcmp(dp->d_name, ".") == 0
|| strcmp(dp->d_name, "..") == 0)
continue; /* skip self and parent */
if (strlen(dir) + strlen(dp->d_name) + 2 > sizeof(name))
fprintf(stderr, "startFromHere: name %s/%s too long\n",
dir, dp->d_name);
else {
sprintf(name, "%s/%s", dir, dp->d_name);
procDirEntries(name,dir,localdbflag);
}
}
printf("\n");
closedir(dfd);
}
/****************************************************************************
PROCDIRENTRIES
process directory entries
****************************************************************************/
static void
procDirEntries(name, dir, indbdirflag)
char *name; /* entry name */
char *dir;
int indbdirflag; /* in database directory flag*/
{
char *ptr;
char *ptr2;
struct stat stbuf;
int localdbflag=0; /* in database directory flag*/
if (lstat(name, &stbuf) == -1) {
fprintf(stderr, "procDirEntries: can't access %s\n", name);
exit(1);
}
printf("."); fflush(stdout);
if ((stbuf.st_mode & S_IFMT) == S_IFLNK) {
procLink(name);
return;
}
if ((stbuf.st_mode & S_IFMT) == S_IFREG) {
processFile(name,indbdirflag);
return;
}
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
/* access the last component (directory) in name */
ptr = (char *) strrchr(name, '/');
if ((ptr2 = (char *) strstr(ptr, "Db")) != NULL ) {
localdbflag=1; /*set in database directory flag*/
}
if ((strcmp(ptr, "/SCCS")) == SAME) {
/* dpath should be composed of - dest_base/SCCS */
strcpy(dpath, dest_base);
strcat(dpath, "/");
strcat(dpath, name);
strcpy(spath, src_base);
strcat(spath, "/");
strcat(spath, name);
createLink();
return;
}
/* for other directories - create hard and continue dirwalk */
strcpy(dpath, dest_base);
strcat(dpath, "/");
strcat(dpath, name);
if (access(dpath, R_OK | F_OK)) {
if ((mkdir(dpath, 0775)) != 0) {
printf("####################################################\n");
printf("procDirEntries: Can't mkdir %s - errno=%d\n", dpath, errno);
printf("####################################################\n");
}
}
dirwalk(name, localdbflag, procDirEntries);
}
return;
}