home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-03-29 | 49.8 KB | 1,864 lines |
- Newsgroups: comp.sources.unix
- From: ejb@ERA.COM (Jay Berkenbilt)
- Subject: v28i003: bcs-2.0 - A Baseline Configuration System, Part02/25
- References: <1.764985670.1461@gw.home.vix.com>
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: ejb@ERA.COM (Jay Berkenbilt)
- Posting-Number: Volume 28, Issue 3
- Archive-Name: bcs-2.0/part02
-
- #!/bin/sh
- # this is bcs.02 (part 2 of bcs-2.0)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file bcs-2.0/lib/file_info.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 2; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping bcs-2.0/lib/file_info.c'
- else
- echo 'x - continuing file bcs-2.0/lib/file_info.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'bcs-2.0/lib/file_info.c' &&
- X * This notice must be kept intact when this file is distributed.
- X *
- X * This file is concerned with maintaining the file information table.
- X */
- X
- #if !defined(lint) && !defined(CODECENTER) || defined(RCS_HDRS)
- /* Define a static function and call it. No warnings this way. */
- static void rcsid(char *s)
- {rcsid("@(#)$Id: file_info.c,v 1.45 1994/03/14 16:53:44 ejb Exp $");}
- #endif /* !lint && !CODECENTER || RCS_HDRS */
- X
- #include "bcs_p.h"
- #include "file_info.h"
- X
- #define ALL_IMPORTANT "*"
- X
- X
- /*
- X * PRIVATE ROUTINES
- X */
- X
- static fi_file_queue_entry new_fi_file_queue_entry(bcs_obj_type bcs_obj,
- X char *name,
- X fi_file_queue_entry parent)
- {
- X fi_file_queue_entry new_file_queue_entry;
- X
- X new_file_queue_entry =
- X bcsi_safe_malloc(bcs_obj->whoami,
- X sizeof(struct fi_file_queue_entry_rec));
- X new_file_queue_entry->name = bcsi_safe_strdup(bcs_obj->whoami, name);
- X if (parent)
- X {
- X char *lastcomp;
- X
- X if ((lastcomp = strrchr(name, PATH_SEP_CHAR)) == NULL)
- X lastcomp = name;
- X else
- X lastcomp++;
- X new_file_queue_entry->path_info =
- X bcsi_path_info_from_parent(bcs_obj, lastcomp, parent->path_info);
- X }
- X else
- X {
- X new_file_queue_entry->path_info = bcsi_get_path_info(bcs_obj, name);
- X }
- X
- X return new_file_queue_entry;
- }
- X
- static void delete_fi_file_queue_entry(fi_file_queue_entry file_queue_entry)
- {
- X if (file_queue_entry)
- X {
- X /* No need to free other fields since they are not copied here */
- X if (file_queue_entry->name)
- X free(file_queue_entry->name);
- X free(file_queue_entry);
- X }
- }
- X
- /*
- X * Constructor for bcs_file_info.
- X *
- X * This routine allocates a new file info structure and initializes
- X * all of its fields to some value. When it is finished, it caches it
- X * in the table. This routine may have side effects that cause other
- X * entries to but added to the table as well.
- X */
- static bcs_file_info new_bcs_file_info(bcs_obj_type bcs_obj,
- X char *filename,
- X path_cache path_info)
- {
- X bcs_file_info file_info;
- X
- X DPRINT((bcs_obj, BCS_DEBUG_TRACE | BCS_DEBUG_LOGIC,
- X "ENTERING new_bcs_file_info(%s)", filename));
- X
- X file_info = bcsi_safe_malloc(bcs_obj->whoami,
- X sizeof(struct bcs_file_info_rec));
- X
- X /* Initialize all fields of file info to SOMETHING */
- X file_info->path_info = path_info;
- X file_info->user_path = bcsi_safe_strdup(bcs_obj->whoami, filename);
- X file_info->clean_path = NULL;
- X file_info->rel_path = NULL;
- X file_info->cont_path = NULL;
- X file_info->indx = FI_UNINITIALIZED;
- X file_info->which = which_uninitialized;
- X file_info->link_type = link_type_uninitialized;
- X file_info->linkpath = NULL;
- X file_info->important = FI_UNINITIALIZED;
- X file_info->unimp_warn = FI_UNINITIALIZED;
- X file_info->stage_params = stage_param_type_uninitialized;
- X file_info->lists = NULL;
- X file_info->staging.has_baseline_counterpart = FI_UNINITIALIZED;
- X file_info->staging.bl_path = NULL;
- X file_info->staging.bl_info = NULL;
- X file_info->staging.is_staged = FI_UNINITIALIZED;
- X
- X pc_insert_file_info(bcs_obj, path_info, file_info);
- X
- X DPRINT((bcs_obj, BCS_DEBUG_TRACE, "LEAVING new_bcs_file_info(%s)",
- X filename));
- X
- X return file_info;
- }
- X
- static bcs_file_info file_info_from_path_info(bcs_obj_type bcs_obj,
- X char *name,
- X path_cache path_info)
- {
- X bcs_file_info file_info = NULL;
- X
- X if (path_info != NULL)
- X {
- X file_info = pc_file_info(bcs_obj, path_info);
- X
- X if (file_info == NULL)
- X {
- X if (name == NULL)
- X name = pc_can_path(bcs_obj, path_info);
- X file_info = new_bcs_file_info(bcs_obj, name, path_info);
- X }
- X }
- X
- X return file_info;
- }
- X
- static void classify_baseline_file(bcs_obj_type bcs_obj,
- X bcs_file_info file_info)
- {
- X char *lastcomp;
- X int important = FALSE;
- X stage_param_type stage_params = fi_normal;
- X bcs_file_info parent_info = NULL;
- X
- X lastcomp = pc_lastcomp(bcs_obj, file_info->path_info);
- X parent_info =
- X file_info_from_path_info(bcs_obj, NULL,
- X pc_parent(bcs_obj, file_info->path_info));
- X
- X if (parent_info == NULL)
- X {
- X /*
- X * This means that / is in the baseline. Although this should
- X * probably never really happen, handle the case anyway.
- X */
- X important = TRUE;
- X stage_params = fi_normal;
- X }
- X else
- X {
- X bcs_stringlist *lists;
- X lists = fi_lists(bcs_obj, parent_info);
- X
- X /*
- X * First perform checks for special files whose importance
- X * and stage parameters cannot be overridden.
- X */
- X
- X /*
- X * If this file is a file internally used by BCS, it is automatically
- X * unimportant so that it doesn't show up in staging areas.
- X * Don't check BL_PATH since it's not important a priori
- X * in the baseline...
- X */
- X if ((strcmp(lastcomp, IMPFILE) == 0) ||
- X (strcmp(lastcomp, UNIMPFILE) == 0) ||
- X (strcmp(lastcomp, AUTOSTAGE) == 0) ||
- X (strcmp(lastcomp, NOSTAGE) == 0) ||
- X (strcmp(lastcomp, NOWARN) == 0) ||
- X (strcmp(fi_rel_path(bcs_obj, file_info), BL_CONF) == 0))
- X {
- X important = TRUE;
- X stage_params = fi_no_mirror;
- X }
- X
- X /* This file is important if it is needed by the CM system */
- X else if (cm_is_precious(bcs_obj, lastcomp))
- X {
- X important = TRUE;
- X stage_params = fi_no_stage;
- X }
- X
- X /*
- X * All of the above checks are for importances that cannot be
- X * overridden. Check the explicit lists no earlier or later
- X * than here. Check implist first since it overrides unimplist.
- X */
- X
- X else
- X {
- X /* If all files in this directory are important, this one is. */
- X if ((lists[implist]->n == 1) &&
- X (strcmp(lists[implist]->data[0], ALL_IMPORTANT) == 0))
- X important = TRUE;
- X
- X /* Check to see whether this file is explicitly important */
- X else if (bcsi_in_stringlist(lastcomp, lists[implist]))
- X important = TRUE;
- X
- X /* Check to see whether this file is explicitly unimportant */
- X else if (bcsi_in_stringlist(lastcomp, lists[unimplist]))
- X important = FALSE;
- X
- X /*
- X * If this file is a link, resolve and test importance of what
- X * it is linked to
- X */
- X else if (pc_islink(bcs_obj, file_info->path_info))
- X {
- X bcs_file_info link_info;
- X
- X link_info = fi_ult_link_info(bcs_obj, file_info);
- X if (link_info != NULL)
- X {
- X important = fi_important(bcs_obj, link_info);
- X }
- X }
- X
- X /* If this file is a directory, it is important */
- X else if (pc_isdir(bcs_obj, file_info->path_info))
- X important = TRUE;
- X
- X /* If this file has a log in the CM system it is important */
- X else if (cm_haslog(bcs_obj, fi_clean_path(bcs_obj, file_info)))
- X important = TRUE;
- X
- X /* Otherwise, this file is unimportant */
- X else
- X important = FALSE;
- X
- X /*
- X * Determine stage params
- X */
- X
- X if (pc_islink(bcs_obj, file_info->path_info))
- X stage_params = fi_no_stage;
- X else
- X {
- X if (bcsi_in_stringlist(lastcomp, lists[autostage]))
- X stage_params = fi_auto_stage;
- X else if (bcsi_in_stringlist(lastcomp, lists[nostage]))
- X stage_params = fi_no_stage;
- X else
- X stage_params = fi_normal;
- X }
- X }
- X }
- X
- X file_info->important = important;
- X file_info->stage_params = stage_params;
- }
- X
- /*
- X * PUBLIC ROUTINES
- X */
- X
- void bcsi_delete_file_info(bcs_file_info file_info)
- {
- X if (file_info)
- X {
- X int i;
- X
- X /* Do not delete the path_cache structure. It deletes us instead. */
- X if (file_info->user_path)
- X free(file_info->user_path);
- X if (file_info->clean_path)
- X free(file_info->clean_path);
- X if (file_info->rel_path)
- X free(file_info->rel_path);
- X if (file_info->cont_path)
- X free(file_info->cont_path);
- X if (file_info->linkpath)
- X free(file_info->linkpath);
- X if (file_info->lists)
- X {
- X for (i = 0; i < NUM_LISTS; i++)
- X fl_delete_flex_list((flex_list *) &(file_info->lists[i]),
- X free);
- X free(file_info->lists);
- X }
- X
- X if (file_info->which == in_staging)
- X if (file_info->staging.bl_path)
- X free(file_info->staging.bl_path);
- X free(file_info);
- X }
- }
- X
- /*
- X * Calculate the baseline path in the proper form for a file.
- X * This routine should only be called for files in a staging area.
- X *
- X * If the baseline prefix for the staging area is an absolute path,
- X * then the baseline path is simply the baseline prefix appended with
- X * the relative path to the file from the top of the staging area.
- X *
- X * If the baseline prefix is relative, then the baseline path
- X * is the baseline prefix prepended with the right number of "../"'s
- X * appended with the name of the path relative to the top of the
- X * staging area. The number of "../"'s should be equal to the number
- X * of directory levels below the top of the staging area this file is.
- X */
- char *bcsi_calc_bl_path(bcs_obj_type bcs_obj, int indx, char *rel_path)
- {
- X char *prefix;
- X char bl_path[MAXPATHLEN];
- X
- X prefix = bcs_obj->staging->data[indx]->bl_path;
- X if (prefix[0] == PATH_SEP_CHAR)
- X {
- X /* Absolute prefix */
- X bcsi_concat_paths(bl_path, prefix, rel_path);
- X }
- X else
- X {
- X bl_path[0] = '\0';
- X if (strlen(rel_path))
- X {
- X char *p;
- X
- X /* Relative prefix */
- X for (p = strchr(rel_path, PATH_SEP_CHAR);
- X p; p = strchr(p + 1, PATH_SEP_CHAR))
- X {
- X strcat(bl_path, "..");
- X strcat(bl_path, PATH_SEP_STR);
- X }
- X }
- X else
- X {
- X bcsi_append_last_component
- X (bl_path, bcs_obj->staging->data[indx]->path.user_path);
- X strcat(bl_path, PATH_SEP_STR);
- X }
- X strcat(bl_path, prefix);
- X if (strlen(rel_path))
- X {
- X strcat(bl_path, PATH_SEP_STR);
- X strcat(bl_path, rel_path);
- X }
- X }
- X
- X return (bcsi_safe_strdup(bcs_obj->whoami, bl_path));
- }
- X
- X
- /*
- X * Remove file info for this path if it exists.
- X */
- void bcsi_remove_file_info(bcs_obj_type bcs_obj, char *name)
- {
- X path_cache path_info;
- X
- X path_info = bcsi_get_path_info(bcs_obj, name);
- X if (path_info)
- X pc_remove_file_info(bcs_obj, path_info);
- }
- X
- /*
- X * This routine takes a directory name and adds its contents, possibly
- X * recursively, to the file information table. If the `resultp'
- X * pointer is non-NULL, it returns a list of the file information
- X * structures sorted by filename. This routine returns a standard BCS
- X * error code.
- X */
- int bcs_examine_dir(bcs_obj_type bcs_obj, char *dir,
- X int recursive,
- X bcs_ed_callback callback, void *cbdata)
- {
- X fi_file_queue file_queue;
- X fi_file_queue_entry queue_entry = NULL;
- X int error = BCS_SUCCESS;
- X
- X DPRINT((bcs_obj, BCS_DEBUG_TRACE, "ENTERING bcs_examine_dir(%s)", dir));
- X
- X /*
- X * Prepare for a tree traversal of the file system starting from
- X * the directory passed in. For each directory in the queue,
- X * append all subdirectories to the queue if recursive is set.
- X */
- X
- X file_queue = (fi_file_queue) fl_new_flex_list(bcs_obj->whoami);
- X
- X /*
- X * Add passed in directory to queue as long as it is really a
- X * directory. Make sure we check specially for baseline
- X * directories since they may really be symbolic links.
- X */
- X if (bcs_isbldir(bcs_obj, dir, NULL, NULL, NULL) || bcs_isdir(bcs_obj, dir))
- X {
- X queue_entry = new_fi_file_queue_entry(bcs_obj, dir, NULL);
- X fl_add_to_tail(bcs_obj->whoami, (flex_list)file_queue, queue_entry);
- X /*
- X * Special case: If dir is really a link, replace its path_info
- X * field with what it is linked to. We know it is linked to a
- X * directory or else bcs_isdir wouldn't have passed.
- X */
- X if (! pc_isdir(bcs_obj, queue_entry->path_info))
- X {
- X queue_entry->path_info =
- X pc_ult_link_info(bcs_obj, queue_entry->path_info);
- X }
- X }
- X else
- X {
- X error = BCS_ERR_USER;
- X bcs_message(bcs_obj, stderr, "%s is not a directory", dir);
- X }
- X
- X /* Traverse the file system depth first */
- X if (! error)
- X {
- X int first = TRUE;
- X bcs_which which;
- X fi_file_queue_entry new_queue_entry;
- X bcs_stringlist entries = NULL;
- X int i;
- X char cur_filename[MAXPATHLEN];
- X char *p;
- X bcs_file_info new_file_info;
- X
- X pc_get_bl_index(bcs_obj, queue_entry->path_info, NULL, &which);
- X while (file_queue->n > 0)
- X {
- X queue_entry = file_queue->data[file_queue->n - 1];
- X new_file_info =
- X file_info_from_path_info(bcs_obj, queue_entry->name,
- X queue_entry->path_info);
- X /*
- X * Do not call the callback for the actual directory passed in.
- X * We only want to act on the contents of this directory.
- X */
- X if (! first)
- X {
- X if (new_file_info && callback)
- X (*callback)(bcs_obj, new_file_info, cbdata);
- X }
- X
- X /* Remove this from the queue, but don't free it yet */
- X fl_delete_range(bcs_obj->whoami, (flex_list) file_queue,
- X file_queue->n - 1, file_queue->n - 1, NULL);
- X
- X /*
- X * Check this entry to see whether we should add its children
- X * to the queue. If this is our first time through or if
- X * we are recursive and this is a directory, then we add
- X * this entry's children to the queue as long as we are not
- X * crossing baseline/staging area boundaries and this is not
- X * a precious directory to the CM system.
- X */
- X
- X if (new_file_info &&
- X (first || (recursive && fi_isdir(bcs_obj, new_file_info))) &&
- X (! cm_is_precious(bcs_obj, queue_entry->name)) &&
- X (fi_which(bcs_obj, new_file_info) == which))
- X {
- X error = bcsi_read_directory_entries(bcs_obj,
- X queue_entry->name,
- X &entries);
- X if (! error)
- X {
- X strcpy(cur_filename, queue_entry->name);
- X /*
- X * Prepare to append each directory entry to the name
- X * of the directory. If the last character of the
- X * path name is already the path separator, just append
- X * as is. If the last component of the path is ".",
- X * overwrite. Otherwise, append the path separator
- X * and then append the entry name.
- X */
- X p = cur_filename + strlen(cur_filename);
- X if (strlen(cur_filename) > 0)
- X {
- X if (*(p-1) != PATH_SEP_CHAR)
- X {
- X if ((strlen(cur_filename) >= 2) &&
- X (*(p-2) == PATH_SEP_CHAR) &&
- X (*(p-1) == '.'))
- X {
- X p--;
- X }
- X else
- X {
- X strcat(cur_filename, PATH_SEP_STR);
- X p++;
- X }
- X }
- X }
- X /* Add entries in reverse so they'll be properly sorted */
- X for (i = entries->n - 1; i >= 0; i--)
- X {
- X strcpy(p, entries->data[i]);
- X new_queue_entry =
- X new_fi_file_queue_entry(bcs_obj,
- X cur_filename,
- X queue_entry);
- X fl_add_to_tail(bcs_obj->whoami,
- X (flex_list) file_queue,
- X new_queue_entry);
- X }
- X fl_delete_flex_list((flex_list *) &entries, free);
- X }
- X }
- X delete_fi_file_queue_entry(queue_entry);
- X first = FALSE;
- X }
- X }
- X
- X fl_delete_flex_list((flex_list *) &file_queue,
- X (fl_free_fn_type)delete_fi_file_queue_entry);
- X
- X DPRINT((bcs_obj, BCS_DEBUG_TRACE, "LEAVING bcs_examine_dir(%s)", dir));
- X return error;
- }
- X
- /*
- X * Look up a file in the file information table. If found, return
- X * resulting structure. Otherwise, insert this file and all
- X * path components leading up to it if necessary.
- X */
- bcs_file_info bcs_get_file_info(bcs_obj_type bcs_obj, char *name)
- {
- X bcs_file_info file_info = NULL;
- X path_cache path_info = NULL;
- X
- X DPRINT((bcs_obj, BCS_DEBUG_TRACE, "ENTERING bcs_get_file_info(%s)",
- X name));
- X
- X path_info = bcsi_get_path_info(bcs_obj, name);
- X file_info = file_info_from_path_info(bcs_obj, name, path_info);
- X
- X DPRINT((bcs_obj, BCS_DEBUG_TRACE, "LEAVING bcs_get_file_info(%s)",
- X name));
- X return file_info;
- }
- X
- void bcs_print_file_info(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X int indx;
- X bcs_which which;
- X char *link_type_str;
- X char *stage_param_str;
- X
- X indx = fi_index(bcs_obj, file_info);
- X which = fi_which(bcs_obj, file_info);
- X
- X printf("%s%s:\n", fi_user_path(bcs_obj, file_info),
- X (fi_isdir(bcs_obj, file_info) ? PATH_SEP_STR : ""));
- X printf(" canonical path: %s\n", fi_can_path(bcs_obj, file_info));
- X printf(" %s\n", (which == in_none) ? "not in baseline or staging area" :
- X ((which == in_baseline) ? "in baseline" : "in staging area"));
- X if (which == in_none)
- X return;
- X printf(" baseline or staging area index: %d\n", indx);
- X printf(" %simportant\n", fi_important(bcs_obj, file_info) ? "" : "un");
- X if (which == in_staging)
- X {
- X if (fi_has_baseline_counterpart(bcs_obj, file_info))
- X printf(" %sstaged\n",
- X fi_is_staged(bcs_obj, file_info) ? "" : "not ");
- X else
- X printf(" no baseline counterpart\n");
- X }
- X
- X switch(fi_link_type(bcs_obj, file_info))
- X {
- X case fi_not_link:
- X link_type_str = "not a link";
- X break;
- X case fi_dangling:
- X link_type_str = "dangling";
- X break;
- X case fi_to_baseline:
- X link_type_str = "link to baseline counterpart";
- X break;
- X case fi_internal:
- X link_type_str = "internal";
- X break;
- X case fi_external:
- X link_type_str = "external";
- X break;
- X default:
- X link_type_str = "unknown";
- X break;
- X }
- X printf(" link type: %s\n", link_type_str);
- X
- X if (which == in_baseline)
- X {
- X switch(fi_stage_params(bcs_obj, file_info))
- X {
- X case fi_normal:
- X stage_param_str = "normal";
- X break;
- X case fi_auto_stage:
- X stage_param_str = "automatically staged";
- X break;
- X case fi_no_stage:
- X stage_param_str = "not stageable";
- X break;
- X case fi_no_mirror:
- X stage_param_str = "not mirrored in staging area";
- X break;
- X default:
- X stage_param_str = "unknown";
- X break;
- X }
- X printf(" stage parameters: %s\n", stage_param_str);
- X }
- }
- X
- char *fi_user_path(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X return file_info->user_path;
- }
- X
- char *fi_clean_path(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->clean_path == NULL)
- X {
- X int indx;
- X bcs_which which;
- X
- X indx = fi_index(bcs_obj, file_info);
- X which = fi_which(bcs_obj, file_info);
- X if (which == in_none)
- X {
- X char *can_path;
- X can_path = fi_can_path(bcs_obj, file_info);
- X file_info->clean_path =
- X bcsi_safe_strdup(bcs_obj->whoami, can_path);
- X }
- X else
- X {
- X char clean_path[MAXPATHLEN];
- X char *cont_path;
- X char *rel_path;
- X
- X cont_path = fi_cont_path(bcs_obj, file_info);
- X rel_path = fi_rel_path(bcs_obj, file_info);
- X bcsi_concat_paths(clean_path, cont_path, rel_path);
- X file_info->clean_path =
- X bcsi_safe_strdup(bcs_obj->whoami, clean_path);
- X }
- X }
- X
- X return file_info->clean_path;
- }
- X
- char *fi_rel_path(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->rel_path == NULL)
- X {
- X int indx;
- X bcs_which which;
- X char *can_path;
- X char *rel_path;
- X char *containing_path;
- X
- X indx = fi_index(bcs_obj, file_info);
- X which = fi_which(bcs_obj, file_info);
- X
- X can_path = fi_can_path(bcs_obj, file_info);
- X if (which == in_baseline)
- X {
- X containing_path =
- X bcs_obj->baseline->data[indx]->path.can_path;
- X }
- X else if (which == in_staging)
- X {
- X containing_path =
- X bcs_obj->staging->data[indx]->path.can_path;
- X }
- X else
- X {
- X bcs_message(bcs_obj, stderr,
- X "INTERNAL ERROR: fi_rel_path called on "
- X "path (%s) neither in baseline nor staging area.",
- X fi_user_path(bcs_obj, file_info));
- X abort();
- X }
- X rel_path = can_path + strlen(containing_path);
- X if (*rel_path)
- X rel_path++;
- X file_info->rel_path = bcsi_safe_strdup(bcs_obj->whoami, rel_path);
- X }
- X
- X return file_info->rel_path;
- }
- X
- char *fi_cont_path(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->cont_path == NULL)
- X {
- X int indx;
- X bcs_which which;
- X char *cont_path;
- X
- X indx = fi_index(bcs_obj, file_info);
- X which = fi_which(bcs_obj, file_info);
- X
- X if (which == in_baseline)
- X {
- X cont_path =
- X bcs_obj->baseline->data[indx]->path.user_path;
- X }
- X else if (which == in_staging)
- X {
- X cont_path =
- X bcs_obj->staging->data[indx]->path.user_path;
- X }
- X else
- X {
- X bcs_message(bcs_obj, stderr,
- X "INTERNAL ERROR: fi_cont_path called on "
- X "path (%s) neither in baseline nor staging area.",
- X fi_user_path(bcs_obj, file_info));
- X abort();
- X }
- X file_info->cont_path = bcsi_safe_strdup(bcs_obj->whoami, cont_path);
- X }
- X
- X return file_info->cont_path;
- }
- X
- char *fi_can_path(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X return pc_can_path(bcs_obj, file_info->path_info);
- }
- X
- int fi_index(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->indx == FI_UNINITIALIZED)
- X {
- X /* Initialize both which and index */
- X pc_get_bl_index(bcs_obj, file_info->path_info,
- X &(file_info->indx),
- X &(file_info->which));
- X }
- X return file_info->indx;
- }
- X
- bcs_which fi_which(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->which == which_uninitialized)
- X (void) fi_index(bcs_obj, file_info);
- X
- X return file_info->which;
- }
- X
- bcs_link_type fi_link_type(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->link_type == link_type_uninitialized)
- X {
- X file_info->link_type = fi_not_link;
- X if (pc_islink(bcs_obj, file_info->path_info))
- X {
- X char *linkpath;
- X int indx;
- X bcs_which which;
- X
- X linkpath = fi_linkpath(bcs_obj, file_info);
- X indx = fi_index(bcs_obj, file_info);
- X which = fi_which(bcs_obj, file_info);
- X
- X if ((which == in_staging) &&
- X (fi_has_baseline_counterpart(bcs_obj, file_info)) &&
- X (strcmp(fi_bl_path(bcs_obj, file_info), linkpath) == 0))
- X {
- X file_info->link_type = fi_to_baseline;
- X }
- X else
- X {
- X /*
- X * Follow links multiple levels to determine what link
- X * type this is. That way if a link goes through
- X * multiple levels, the link type of this link
- X * will be its ultimate destination.
- X */
- X bcs_file_info link_info;
- X bcs_which lwhich;
- X link_info = fi_ult_link_info(bcs_obj, file_info);
- X
- X if (link_info)
- X {
- X lwhich = fi_which(bcs_obj, link_info);
- X if (which == lwhich)
- X file_info->link_type = fi_internal;
- X else
- X file_info->link_type = fi_external;
- X }
- X else
- X file_info->link_type = fi_dangling;
- X }
- X }
- X else
- X file_info->link_type = fi_not_link;
- X }
- X
- X return file_info->link_type;
- }
- X
- char *fi_linkpath(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->linkpath == NULL)
- X {
- X file_info->linkpath =
- X bcsi_safe_strdup(bcs_obj->whoami,
- X pc_linkpath(bcs_obj, file_info->path_info));
- X }
- X
- X return file_info->linkpath;
- }
- X
- bcs_file_info fi_ult_link_info(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X bcs_file_info link_info = NULL;
- X path_cache ult_path_info;
- X
- X ult_path_info = pc_ult_link_info(bcs_obj, file_info->path_info);
- X if (ult_path_info)
- X {
- X link_info = file_info_from_path_info(bcs_obj, NULL,
- X ult_path_info);
- X }
- X
- X return link_info;
- }
- X
- int fi_important(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->important == FI_UNINITIALIZED)
- X {
- X int indx;
- X bcs_which which;
- X struct stat *statbuf;
- X
- X file_info->important = FALSE;
- X indx = fi_index(bcs_obj, file_info);
- X which = fi_which(bcs_obj, file_info);
- X statbuf = pc_statbuf(bcs_obj, file_info->path_info);
- X
- X if (which == in_staging)
- X {
- X /*
- X * Initialize non-pointer members staging structure as well
- X * as important
- X */
- X file_info->staging.has_baseline_counterpart = FALSE;
- X file_info->staging.is_staged = FALSE;
- X
- X if (strcmp(fi_rel_path(bcs_obj, file_info), BL_PATH) == 0)
- X {
- X file_info->staging.has_baseline_counterpart = FALSE;
- X file_info->important = TRUE;
- X }
- X else
- X {
- X bcs_file_info bl_file_info;
- X
- X bl_file_info = fi_bl_info(bcs_obj, file_info);
- X if (bl_file_info)
- X {
- X file_info->staging.has_baseline_counterpart = TRUE;
- X if (fi_stage_params(bcs_obj, bl_file_info) == fi_no_mirror)
- X file_info->important = FALSE;
- X else
- X file_info->important =
- X fi_important(bcs_obj, bl_file_info);
- X if (file_info->important)
- X {
- X if (fi_link_type(bcs_obj, bl_file_info) == fi_not_link)
- X file_info->staging.is_staged =
- X (! pc_islink(bcs_obj, file_info->path_info));
- X }
- X else
- X /* Never consider unimportant files staged */
- X file_info->staging.is_staged = FALSE;
- X }
- X else
- X {
- X file_info->staging.has_baseline_counterpart = FALSE;
- X file_info->important = FALSE;
- X }
- X }
- X DPRINT((bcs_obj, BCS_DEBUG_LOGIC,
- X "fi_important: has_baseline_counterpart = %d, "
- X "staged = %d",
- X file_info->staging.has_baseline_counterpart,
- X file_info->staging.is_staged));
- X }
- X else if (which == in_baseline)
- X {
- X classify_baseline_file(bcs_obj, file_info);
- X }
- X
- X DPRINT((bcs_obj, BCS_DEBUG_LOGIC,
- X "fi_important(%s): important = %d",
- X fi_user_path(bcs_obj, file_info), file_info->important));
- X }
- X
- X return file_info->important;
- }
- X
- int fi_unimp_warn(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (file_info->unimp_warn == FI_UNINITIALIZED)
- X {
- X char nowarn_file[MAXPATHLEN];
- X int indx;
- X
- X file_info->unimp_warn = FALSE;
- X indx = fi_index(bcs_obj, file_info);
- X
- X /*
- X * Check to see whether this is an unimportant file that a warning
- X * should be issued about. This would be the case if this file
- X * is a directory or has a special suffix and if the NOWARN file
- X * doesn't exist in its directory in the baseline.
- X */
- X if (! fi_important(bcs_obj, file_info))
- X {
- X char *p;
- X
- X bcsi_concat_paths
- X (nowarn_file,
- X bcs_obj->baseline->data[indx]->path.user_path,
- X fi_rel_path(bcs_obj, file_info));
- X if ((p = strrchr(nowarn_file, PATH_SEP_CHAR)) != NULL)
- X *p = '\0';
- X else
- X nowarn_file[0] = '\0';
- X bcsi_concat_paths(nowarn_file, nowarn_file, NOWARN);
- X
- X if (! bcsi_exists(bcs_obj, nowarn_file))
- X {
- X /*
- X * Set warning flag if this file ends with a specified
- X * suffix or is a directory
- X */
- X if (fi_isdir(bcs_obj, file_info))
- X file_info->unimp_warn = TRUE;
- X else
- X {
- X bcs_stringlist unimp_warn_suffixes;
- X char *cur_suffix;
- X int name_len;
- X int suf_len;
- X int i;
- X char *filename;
- X
- X filename = fi_can_path(bcs_obj, file_info);
- X name_len = strlen(filename);
- X unimp_warn_suffixes =
- X bcs_obj->baseline->data[indx]->
- X unimp_warn_suffixes;
- X for (i = 0; i < unimp_warn_suffixes->n; i++)
- X {
- X cur_suffix = unimp_warn_suffixes->data[i];
- X suf_len = strlen(cur_suffix);
- X if ((name_len >= suf_len) &&
- X (strcmp(&filename[name_len - suf_len],
- X cur_suffix) == 0))
- X {
- X file_info->unimp_warn = TRUE;
- X }
- X }
- X }
- X }
- X }
- X }
- X
- X return file_info->unimp_warn;
- }
- X
- stage_param_type fi_stage_params(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (fi_which(bcs_obj, file_info) != in_baseline)
- X return fi_no_mirror;
- X
- X if (file_info->stage_params == stage_param_type_uninitialized)
- X {
- X (void) fi_important(bcs_obj, file_info);
- X }
- X
- X return file_info->stage_params;
- }
- X
- bcs_stringlist *fi_lists(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (! fi_isdir(bcs_obj, file_info))
- X {
- X bcs_message(bcs_obj, stderr,
- X "INTERNAL ERROR: fi_lists called on file (%s) "
- X "that is not a directory.",
- X fi_user_path(bcs_obj, file_info));
- X abort();
- X }
- X
- X if (file_info->lists == NULL)
- X {
- X char tmppath[MAXPATHLEN];
- X char *p;
- X bcs_stringlist *lists;
- X
- X lists = bcsi_safe_malloc(bcs_obj->whoami,
- X NUM_LISTS * sizeof(bcs_stringlist));
- X
- X strcpy(tmppath, fi_can_path(bcs_obj, file_info));
- X strcat(tmppath, PATH_SEP_STR);
- X p = tmppath + strlen(tmppath);
- X
- X strcpy(p, IMPFILE);
- X lists[implist] = bcsi_file_to_stringlist(bcs_obj, tmppath);
- X
- X strcpy(p, UNIMPFILE);
- X lists[unimplist] = bcsi_file_to_stringlist(bcs_obj, tmppath);
- X
- X strcpy(p, AUTOSTAGE);
- X lists[autostage] = bcsi_file_to_stringlist(bcs_obj, tmppath);
- X
- X strcpy(p, NOSTAGE);
- X lists[nostage] = bcsi_file_to_stringlist(bcs_obj, tmppath);
- X
- X file_info->lists = lists;
- X }
- X
- X return file_info->lists;
- }
- X
- int fi_has_baseline_counterpart(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (fi_which(bcs_obj, file_info) != in_staging)
- X return FALSE;
- X
- X if (file_info->staging.has_baseline_counterpart == FI_UNINITIALIZED)
- X {
- X (void) fi_important(bcs_obj, file_info);
- X }
- X
- X return file_info->staging.has_baseline_counterpart;
- }
- X
- char *fi_bl_path(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (fi_which(bcs_obj, file_info) != in_staging)
- X {
- X bcs_message(bcs_obj, stderr,
- X "INTERNAL ERROR: fi_bl_path called on file (%s) "
- X "not in staging area.",
- X fi_user_path(bcs_obj, file_info));
- X abort();
- X }
- X
- X if (file_info->staging.bl_path == NULL)
- X {
- X int indx;
- X char *rel_path;
- X
- X indx = fi_index(bcs_obj, file_info);
- X rel_path = fi_rel_path(bcs_obj, file_info);
- X
- X file_info->staging.bl_path =
- X bcsi_calc_bl_path(bcs_obj, indx, rel_path);
- X }
- X return file_info->staging.bl_path;
- }
- X
- bcs_file_info fi_bl_info(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (fi_which(bcs_obj, file_info) != in_staging)
- X {
- X bcs_message(bcs_obj, stderr,
- X "INTERNAL ERROR: fi_bl_info called on file (%s) "
- X "not in staging area.",
- X fi_user_path(bcs_obj, file_info));
- X abort();
- X }
- X
- X if (file_info->staging.bl_info == NULL)
- X {
- X char *bl_path;
- X char tmppath[MAXPATHLEN];
- X bcs_file_info bl_file_info;
- X
- X bl_path = fi_bl_path(bcs_obj, file_info);
- X if (bl_path[0] == PATH_SEP_CHAR)
- X strcpy(tmppath, bl_path);
- X else
- X bcsi_resolve_readlink(tmppath, bl_path,
- X fi_can_path(bcs_obj, file_info));
- X
- X DPRINT((bcs_obj, BCS_DEBUG_LOGIC,
- X "new_file_info: baseline_path = %s = %s",
- X bl_path, tmppath));
- X bl_file_info = bcs_get_file_info(bcs_obj, tmppath);
- X
- X /*
- X * Don't count this if the counterpart is not really in the
- X * baseline. This could happen if you have staging areas
- X * under the baseline and don't put them in UNIMPFILE.
- X */
- X if (bl_file_info && (fi_which(bcs_obj, bl_file_info) != in_baseline))
- X bl_file_info = NULL;
- X
- X file_info->staging.bl_info = bl_file_info;
- X }
- X
- X return file_info->staging.bl_info;
- }
- X
- int fi_is_staged(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X if (fi_which(bcs_obj, file_info) != in_staging)
- X return FALSE;
- X
- X if (file_info->staging.is_staged == FI_UNINITIALIZED)
- X {
- X (void) fi_important(bcs_obj, file_info);
- X }
- X
- X return file_info->staging.is_staged;
- }
- X
- int fi_writable(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X return ((pc_statbuf(bcs_obj, file_info->path_info)->st_mode & S_IWUSR)
- X ? TRUE : FALSE);
- }
- X
- int fi_isdir(bcs_obj_type bcs_obj, bcs_file_info file_info)
- {
- X return pc_isdir(bcs_obj, file_info->path_info);
- }
- SHAR_EOF
- echo 'File bcs-2.0/lib/file_info.c is complete' &&
- chmod 0444 bcs-2.0/lib/file_info.c ||
- echo 'restore of bcs-2.0/lib/file_info.c failed'
- Wc_c="`wc -c < 'bcs-2.0/lib/file_info.c'`"
- test 30386 -eq "$Wc_c" ||
- echo 'bcs-2.0/lib/file_info.c: original size 30386, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= bcs-2.0/lib/file_info.h ==============
- if test -f 'bcs-2.0/lib/file_info.h' -a X"$1" != X"-c"; then
- echo 'x - skipping bcs-2.0/lib/file_info.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting bcs-2.0/lib/file_info.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'bcs-2.0/lib/file_info.h' &&
- /*
- X * $Id: file_info.h,v 1.7 1994/03/07 21:47:41 qjb Exp $
- X * $Source: /local/tmp/bcs-2.0/lib/RCS/file_info.h,v $
- X * $Author: qjb $
- X *
- X * Copyright (C) 1994 E. Jay Berkenbilt
- X *
- X * This file is part of BCS. BCS may be distributed according to the terms
- X * of the General Public License and/or the Artistic License. See the
- X * `COPYING' and `Artistic' files with the source distribution for details.
- X * This notice must be kept intact when this file is distributed.
- X *
- X * This file defines data structures private to file_info.c
- X */
- X
- #ifndef __FILE_INFO_H__
- #define __FILE_INFO_H__
- X
- #if !defined(lint) && !defined(CODECENTER) || defined(RCS_HDRS)
- /* Define a static function and call it. No warnings this way. */
- static void rcsid_file_info_h(char *s)
- {rcsid_file_info_h("@(#)$Id: file_info.h,v 1.7 1994/03/07 21:47:41 qjb Exp $");}
- #endif /* !lint && !CODECENTER || RCS_HDRS */
- X
- #define FI_UNINITIALIZED -1
- X
- typedef struct fi_file_queue_entry_rec {
- X char *name;
- X path_cache path_info;
- } *fi_file_queue_entry;
- X
- FL_DEFINE(fi_file_queue_rec, fi_file_queue, fi_file_queue_entry);
- X
- typedef struct fi_link_info_rec {
- X char *linkpath; /* where this link immediately points */
- X char *ult_linkpath; /* where this link eventually points */
- } *fi_link_info;
- X
- struct bcs_file_info_rec {
- X path_cache path_info; /* path cache entry containing us */
- X char *user_path; /* filename relative to how user specified */
- X char *clean_path; /* pathname to file with respect to bl/st dir */
- X char *cont_path; /* user path of containing bl/staging dir */
- X char *rel_path; /* path relative to top of bl/staging dir */
- X int indx; /* which baseline/staging area this is in */
- X bcs_which which; /* baseline or staging area */
- X bcs_link_type link_type;
- X char *linkpath; /* valid only if link_type != fi_not_link */
- X int important;
- X int unimp_warn; /* warn if unimportant and has special suffix */
- X stage_param_type stage_params; /* valid only if in baseline */
- X bcs_stringlist *lists; /* important, unimportant, etc. lists */
- X struct {
- X int has_baseline_counterpart;
- X char *bl_path; /* path to baseline counterpart */
- X struct bcs_file_info_rec *bl_info; /* fi record for bl counterpart */
- X int is_staged; /* whether file is staged */
- X } staging; /* valid only if in staging area */
- };
- X
- /* For various per-directory configuration files */
- enum { implist, unimplist, autostage, nostage };
- #define NUM_LISTS (nostage + 1)
- X
- #endif /* __FILE_INFO_H__ */
- SHAR_EOF
- chmod 0444 bcs-2.0/lib/file_info.h ||
- echo 'restore of bcs-2.0/lib/file_info.h failed'
- Wc_c="`wc -c < 'bcs-2.0/lib/file_info.h'`"
- test 2509 -eq "$Wc_c" ||
- echo 'bcs-2.0/lib/file_info.h: original size 2509, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= bcs-2.0/lib/find_cmd ==============
- if test -f 'bcs-2.0/lib/find_cmd' -a X"$1" != X"-c"; then
- echo 'x - skipping bcs-2.0/lib/find_cmd (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting bcs-2.0/lib/find_cmd (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'bcs-2.0/lib/find_cmd' &&
- #!/bin/sh
- #
- # $Id: find_cmd,v 1.1 1993/08/24 04:18:16 qjb Exp $
- # $Source: /local/tmp/bcs-2.0/lib/RCS/find_cmd,v $
- # $Author: qjb $
- #
- # Find first occurence command in the path
- #
- X
- whoami=`basename $0`
- if test $# -ne 1; then
- X echo "Usage: $whoami command" 1>&2
- X exit 1
- fi
- X
- cmd=$1
- X
- IFS=:
- for dir in $PATH; do
- X if test "$dir" != "" -a "$dir" != "."; then
- X if test -f $dir/$cmd; then
- X echo $dir/$cmd
- X exit 0
- X fi
- X fi
- done
- X
- Xexit 0
- SHAR_EOF
- chmod 0444 bcs-2.0/lib/find_cmd ||
- echo 'restore of bcs-2.0/lib/find_cmd failed'
- Wc_c="`wc -c < 'bcs-2.0/lib/find_cmd'`"
- test 445 -eq "$Wc_c" ||
- echo 'bcs-2.0/lib/find_cmd: original size 445, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= bcs-2.0/lib/flexlist.c ==============
- if test -f 'bcs-2.0/lib/flexlist.c' -a X"$1" != X"-c"; then
- echo 'x - skipping bcs-2.0/lib/flexlist.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting bcs-2.0/lib/flexlist.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'bcs-2.0/lib/flexlist.c' &&
- /*
- X * $Id: flexlist.c,v 1.11 1994/03/07 21:47:41 qjb Exp $
- X * $Source: /local/tmp/bcs-2.0/lib/RCS/flexlist.c,v $
- X * $Author: qjb $
- X *
- X * Copyright (C) 1994 E. Jay Berkenbilt
- X *
- X * This file is part of BCS. BCS may be distributed according to the terms
- X * of the General Public License and/or the Artistic License. See the
- X * `COPYING' and `Artistic' files with the source distribution for details.
- X * This notice must be kept intact when this file is distributed.
- X *
- X * This file provides an implementation of dynamic arrays with efficient
- X * insert and lookup but inefficient delete.
- X */
- X
- #if !defined(lint) && !defined(CODECENTER) || defined(RCS_HDRS)
- /* Define a static function and call it. No warnings this way. */
- static void rcsid(char *s)
- {rcsid("@(#)$Id: flexlist.c,v 1.11 1994/03/07 21:47:41 qjb Exp $");}
- #endif /* !lint && !CODECENTER || RCS_HDRS */
- X
- #include "bcs_p.h"
- X
- flex_list fl_new_flex_list(char *whoami)
- {
- X int i;
- X flex_list list;
- X
- X list = bcsi_safe_malloc(whoami, sizeof(struct flex_list_rec));
- X
- X list->max = FLEX_MAX_INIT;
- X list->n = 0;
- X list->data = bcsi_safe_malloc(whoami, FLEX_MAX_INIT * sizeof(fl_pointer));
- X
- X for (i = 0; i < FLEX_MAX_INIT; i++)
- X list->data[i] = NULL;
- X
- X return list;
- }
- X
- void fl_delete_flex_list(flex_list *list, fl_free_fn_type free_fn)
- {
- X if (*list)
- X {
- X if (free_fn)
- X {
- X int i;
- X for (i = 0; i < (*list)->n; i++)
- X if ((*list)->data[i])
- X {
- X (*free_fn)((*list)->data[i]);
- X (*list)->data[i] = NULL;
- X }
- X }
- X if ((*list)->data)
- X free((*list)->data);
- X free (*list);
- X *list = NULL;
- X }
- }
- X
- void fl_add_to_tail (char *whoami, flex_list list, fl_pointer data)
- {
- X fl_insert(whoami, list, list->n, data);
- }
- X
- void fl_delete_range(char *whoami, flex_list list, int start, int end,
- X fl_free_fn_type free_fn)
- {
- X int i;
- X int num_items;
- X
- X num_items = end - start + 1;
- X
- X for (i = start; i <= end; i++)
- X if (list->data[i])
- X {
- X if (free_fn)
- X (*free_fn)(list->data[i]);
- X list->data[i] = NULL;
- X }
- X
- X for (i = end + 1; i < list->n; i++)
- X list->data[i - num_items] = list->data[i];
- X list->n -= num_items;
- }
- X
- void fl_insert(char *whoami, flex_list list, int indx, fl_pointer data)
- {
- X fl_pointer *newdata;
- X int i;
- X
- X if (list->n + 1 > list->max)
- X {
- X newdata = bcsi_safe_malloc(whoami, list->max * 2 * sizeof(fl_pointer));
- X for (i = 0; i < list->max; i++)
- X newdata[i] = list->data[i];
- X for (i = list->max; i < 2 * list->max; i++)
- X newdata[i] = NULL;
- X free(list->data);
- X list->data = newdata;
- X list->max *= 2;
- X }
- X
- X for (i = list->n; i > indx; i--)
- X list->data[i] = list->data[i - 1];
- X
- X list->data[indx] = data;
- X list->n++;
- }
- SHAR_EOF
- chmod 0444 bcs-2.0/lib/flexlist.c ||
- echo 'restore of bcs-2.0/lib/flexlist.c failed'
- Wc_c="`wc -c < 'bcs-2.0/lib/flexlist.c'`"
- test 2676 -eq "$Wc_c" ||
- echo 'bcs-2.0/lib/flexlist.c: original size 2676, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= bcs-2.0/lib/init.c ==============
- if test -f 'bcs-2.0/lib/init.c' -a X"$1" != X"-c"; then
- echo 'x - skipping bcs-2.0/lib/init.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting bcs-2.0/lib/init.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'bcs-2.0/lib/init.c' &&
- /*
- X * $Id: init.c,v 1.36 1994/03/07 21:47:41 qjb Exp $
- X * $Source: /local/tmp/bcs-2.0/lib/RCS/init.c,v $
- X * $Author: qjb $
- X *
- X * Copyright (C) 1994 E. Jay Berkenbilt
- X *
- X * This file is part of BCS. BCS may be distributed according to the terms
- X * of the General Public License and/or the Artistic License. See the
- X * `COPYING' and `Artistic' files with the source distribution for details.
- X * This notice must be kept intact when this file is distributed.
- X *
- X * This file handles BCS startup operations.
- X */
- X
- #if !defined(lint) && !defined(CODECENTER) || defined(RCS_HDRS)
- /* Define a static function and call it. No warnings this way. */
- static void rcsid(char *s)
- {rcsid("@(#)$Id: init.c,v 1.36 1994/03/07 21:47:41 qjb Exp $");}
- #endif /* !lint && !CODECENTER || RCS_HDRS */
- X
- #include "bcs_p.h"
- #include "version.h"
- #include "builddate.h"
- X
- #define BL_CONF_COMMENT '#'
- #define BL_CONF_SEPARATOR ':'
- X
- /**
- X ** PRIVATE ROUTINES
- X **/
- X
- /*
- X * "Constructor" for bcs_obj
- X */
- static bcs_obj_type new_bcs_obj(char *whoami)
- {
- X bcs_obj_type obj;
- X
- X obj = bcsi_safe_malloc(whoami, sizeof(struct bcs_obj_rec));
- X
- X obj->whoami = whoami; /* just use memory from argv[0] */
- #ifdef DEBUG
- X obj->debug_flags = 0;
- #endif
- X obj->baseline = NULL;
- X obj->staging = NULL;
- X obj->recursive = FALSE;
- X obj->no_action = FALSE;
- X
- X return obj;
- }
- X
- X
- /*
- X * This routine checks to see whether cmd_option was specified on the
- X * commandline or, if not, whether the environment variable in env_var
- X * is set. If required is TRUE, it requires one of these to be set.
- X * If neither case occurs, an error status is returned
- X * (BCS_ERR_USAGE). Otherwise, result points to the value.
- X */
- static int get_env_flag(bcs_obj_type bcs_obj,
- X char *env_var, char *cmd_option,
- X int argc, char *argv[],
- X int required, char **result)
- {
- X int i;
- X /* Search for the commandline option */
- X
- X for (i = 1; i < argc; i++)
- X {
- X if (argv[i] && (strcmp(argv[i], cmd_option) == 0))
- X {
- X if (i + 1 >= argc)
- X {
- X bcs_message(bcs_obj, stderr,
- X "the %s option requires an argument.", cmd_option);
- X return BCS_ERR_USAGE;
- X }
- X else
- X {
- X argv[i] = NULL;
- X *result = argv[i + 1];
- X argv[i + 1] = NULL;
- X return BCS_SUCCESS;
- X }
- X }
- X }
- X
- X /* If not found, search for the environment variable */
- X if ((*result = getenv(env_var)) == NULL)
- X {
- X if (required)
- X {
- X bcs_message(bcs_obj, stderr,
- X "either the %s option must be specified or the "
- X "%s environment variable must be set.",
- X cmd_option, env_var);
- X return BCS_ERR_USAGE;
- X }
- X else
- X {
- X *result = NULL;
- X }
- X }
- X
- X return BCS_SUCCESS;
- }
- X
- #ifdef DEBUG
- static int find_dstring(char *dstring, char *keyword)
- {
- X char *p;
- X int found = FALSE;
- X
- X if ((p = strstr(dstring, keyword)) != NULL)
- X {
- X /*
- X * This is it if the the keyword starts at the beginning
- X * of the string or after a colon and ends at the end
- X * of the string or before a colon.
- X */
- X found = (((p == dstring) || (*(p-1) == ':')) &&
- X ((*(p + strlen(keyword)) == '\0') ||
- X (*(p + strlen(keyword)) == ':')));
- X }
- X
- X return found;
- }
- #endif /* DEBUG */
- X
- static int parse_dflags(bcs_obj_type bcs_obj, int argc, char *argv[])
- {
- X int status = BCS_SUCCESS;
- X char *result;
- X
- X status = get_env_flag(bcs_obj, DEBUG_ENV, "--debug", argc, argv,
- X FALSE, &result);
- X if ((status == BCS_SUCCESS) && result)
- X {
- #ifdef DEBUG
- X bcs_obj->debug_flags = 0;
- X if (find_dstring(result, "all"))
- X bcs_obj->debug_flags = -1;
- X else
- X {
- X if (find_dstring(result, "logic"))
- X bcs_obj->debug_flags |= BCS_DEBUG_LOGIC;
- X if (find_dstring(result, "trace"))
- X bcs_obj->debug_flags |= BCS_DEBUG_TRACE;
- X if (find_dstring(result, "verbose"))
- X bcs_obj->debug_flags |= BCS_DEBUG_VERBOSE;
- X if (find_dstring(result, "path"))
- X bcs_obj->debug_flags |= BCS_DEBUG_PATH;
- X }
- #else
- X bcs_message(bcs_obj, stderr,
- X "%s is set or --debug is specified on the commandline, "
- X "but DEBUG was not defined at compile time.",
- X DEBUG_ENV);
- X status = BCS_ERR_USAGE;
- #endif /* DEBUG */
- X }
- X
- X return status;
- }
- X
- static bcs_stringlist parse_colon_string(bcs_obj_type bcs_obj, char *str)
- {
- X char *workstring;
- X bcs_stringlist list;
- X char *start, *end;
- X int done = FALSE;
- X
- X workstring = bcsi_safe_strdup(bcs_obj->whoami, str);
- X list = (bcs_stringlist)fl_new_flex_list(bcs_obj->whoami);
- X
- X start = workstring;
- X
- X do {
- X if ((end = strchr(start, ':')) == NULL)
- X {
- X end = start + strlen(start);
- X done = TRUE;
- X }
- X else
- X {
- X *end = '\0';
- X }
- X
- X fl_add_to_tail(bcs_obj->whoami, (flex_list)list,
- X bcsi_safe_strdup(bcs_obj->whoami, start));
- X start = end + 1;
- X } while (! done);
- X
- X free (workstring);
- X return list;
- }
- X
- static int parse_colon_path(bcs_obj_type bcs_obj, int argc, char *argv[],
- X char *env_var, char *cmd_opt,
- X bcs_stringlist *list)
- {
- X int status = BCS_SUCCESS;
- X char *result;
- X int i;
- X
- X status = get_env_flag(bcs_obj, env_var, cmd_opt, argc, argv,
- X TRUE, &result);
- X if (status == BCS_SUCCESS)
- X {
- X (*list) = parse_colon_string(bcs_obj, result);
- X
- X DPRINT((bcs_obj, BCS_DEBUG_LOGIC, "%s:", env_var));
- X for (i = 0; i < (*list)->n; i++)
- X {
- X DPRINT((bcs_obj, BCS_DEBUG_LOGIC, " %s",
- X (char *)(*list)->data[i]));
- X }
- X }
- X
- X return status;
- }
- X
- static int get_baseline(bcs_obj_type bcs_obj, int argc, char *argv[],
- X bcs_stringlist *list)
- {
- X return parse_colon_path(bcs_obj, argc, argv, BASELINE_ENV,
- X "--baseline", list);
- }
- X
- static int get_staging(bcs_obj_type bcs_obj, int argc, char *argv[],
- X bcs_stringlist *list)
- {
- X return parse_colon_path(bcs_obj, argc, argv, STAGING_ENV,
- X "--staging", list);
- }
- X
- X
- static void init_path_info(bcs_obj_type bcs_obj,
- X char *pathname, bcs_path_info *path)
- {
- X path_cache path_info;
- X char tmppath[MAXPATHLEN];
- X struct stat *statbuf;
- X
- X /*
- X * For baseline and staging area directories, a special case
- X * of allowing the directory to be a symbolic link is implemented.
- X * The canonical path of the baseline or staging area directories
- X * is the real directory.
- X */
- X
- X strcpy(tmppath, pathname);
- X if (strlen(tmppath))
- X {
- X strcat(tmppath, PATH_SEP_STR);
- X strcat(tmppath, ".");
- X }
- X path->user_path = pathname;
- X path_info = bcsi_get_path_info(bcs_obj, tmppath);
- X if (path_info == NULL)
- X {
- X bcs_message(bcs_obj, stderr,
- X "baseline or staging area directory %s does not exist",
- X pathname);
- X exit (BCS_ERR_SYSTEM);
- X }
- X path->can_path =
- X bcsi_safe_strdup(bcs_obj->whoami, pc_can_path(bcs_obj, path_info));
- X statbuf = pc_statbuf(bcs_obj, path_info);
- X path->ino = statbuf->st_ino;
- X path->dev = statbuf->st_dev;
- }
- X
- static bcs_baseline_info new_baseline_info(bcs_obj_type bcs_obj, char *path)
- {
- X bcs_baseline_info bi;
- X
- X bi = bcsi_safe_malloc(bcs_obj->whoami,
- X sizeof(struct bcs_baseline_info_rec));
- X init_path_info(bcs_obj, path, &bi->path);
- X bi->cm_name = NULL;
- X bi->secure = FALSE;
- X bi->unimp_warn_suffixes = (bcs_stringlist)fl_new_flex_list(bcs_obj->whoami);
- X
- X return bi;
- }
- X
- bcs_staging_info new_staging_info(bcs_obj_type bcs_obj, char *path)
- {
- X bcs_staging_info si;
- X
- X si = bcsi_safe_malloc(bcs_obj->whoami,
- X sizeof(struct bcs_staging_info_rec));
- X init_path_info(bcs_obj, path, &si->path);
- X si->bl_path = NULL;
- X
- X return si;
- }
- X
- int check_for_file(bcs_obj_type bcs_obj, bcs_stringlist paths, char *file)
- {
- X int error = FALSE;
- X char tmppath[MAXPATHLEN];
- X int i;
- X
- X /* Make sure each component is a directory */
- X for (i = 0; i < paths->n; i++)
- X {
- X strcpy(tmppath, paths->data[i]);
- X if (strlen(tmppath))
- X {
- X strcat(tmppath, PATH_SEP_STR);
- X strcat(tmppath, ".");
- X }
- X
- X if (bcs_isdir(bcs_obj, paths->data[i]) ||
- X bcs_isdir(bcs_obj, tmppath))
- X {
- X strcpy(tmppath, paths->data[i]);
- X strcat(tmppath, PATH_SEP_STR);
- X strcat(tmppath, file);
- X if (! bcsi_readable(bcs_obj, tmppath))
- X {
- X error = TRUE;
- X bcs_message(bcs_obj, stderr,
- X "%s does not exist or is not readable.", tmppath);
- X }
- X }
- X else
- X {
- X error = TRUE;
- X bcs_message(bcs_obj, stderr, "%s is not a directory.",
- X paths->data[i]);
- X }
- X }
- X
- X return error;
- }
- X
- /*
- X * Read the baseline prefix file in the given directory. This routine
- X * exits if it fails for any reason. Checks should be performed in advance
- X * to make sure the file exists and is readable.
- X */
- char *read_bl_path(bcs_obj_type bcs_obj, char *path)
- {
- X char tmppath[MAXPATHLEN];
- X FILE *prefix;
- X char result[MAXPATHLEN];
- X
- X strcpy(tmppath, path);
- X strcat(tmppath, PATH_SEP_STR);
- X strcat(tmppath, BL_PATH);
- X
- X if ((prefix = fopen(tmppath, "r")) == NULL)
- X {
- X bcs_message(bcs_obj, stderr, "can't open %s for reading; exiting.",
- X tmppath);
- X exit(BCS_ERR_SYSTEM);
- X }
- X
- X mem_zero(result, sizeof(result));
- X if (fgets(result, sizeof(result) - 1, prefix) == NULL)
- X {
- X bcs_message(bcs_obj, stderr, "failure reading %s; exiting",
- X path);
- X exit(BCS_ERR_SYSTEM);
- X }
- X
- X fclose(prefix);
- X
- X /* Strip off newline if any */
- X if ((strlen(result) > 0) && (result[strlen(result) - 1] == '\n'))
- X result[strlen(result) - 1] = '\0';
- X
- X return bcsi_safe_strdup(bcs_obj->whoami, result);
- }
- X
- /*
- X * Read baseline conf files. File should have already been shown to exist
- X * and be readable before this routine is called.
- X */
- static int parse_bl_conf(bcs_obj_type bcs_obj, bcs_baseline_info bl_info)
- {
- X FILE *bl;
- X char filename[MAXPATHLEN];
- X char line[BUFSIZ + 1];
- X char *p;
- X char *key, *value;
- X int lineno;
- X int error = FALSE;
- X
- X strcpy(filename, bl_info->path.user_path);
- X strcat(filename, PATH_SEP_STR);
- X strcat(filename, BL_CONF);
- X
- X if ((bl = fopen(filename, "r")) == NULL)
- X {
- X bcs_message(bcs_obj, stderr,
- X "parse_bl_conf called but %s cannot be opened for "
- X "reading", filename);
- X exit(BCS_ERR_INTERNAL);
- X }
- X
- X DPRINT((bcs_obj, BCS_DEBUG_VERBOSE, "reading %s...", filename));
- X
- X /*
- X * Read file a line at a time separating key from value.
- X * Each line is of the format key [ : value ]
- X * Spacing is not important. If no value is present, it is taken
- X * to be a null string.
- X */
- X lineno = 0;
- X mem_zero(line, sizeof(line));
- X while ((fgets(line, sizeof(line) - 1, bl)) != NULL)
- SHAR_EOF
- true || echo 'restore of bcs-2.0/lib/init.c failed'
- fi
- echo 'End of bcs-2.0 part 2'
- echo 'File bcs-2.0/lib/init.c is continued in part 3'
- echo 3 > _shar_seq_.tmp
- exit 0
-