home *** CD-ROM | disk | FTP | other *** search
- /*
- * MARK
- * Mark Directory
- * Version 1.7
- *
- * Sunil William Savkar
- * sunil@hal.com
- * Copyright (c) 1991
- * All Rights Reserved
- *
- * DISCLOSURE
- *
- * This source may be modified or copied freely. The intent
- * is the free distribution of a useful utility used for moving
- * between directories. Any modifications and additions, along
- * with bug reports should be sent to the author, so all might
- * benefit!
- *
- * DESCRIPTION
- *
- * Mark directory utility used in conjunction with the
- * setd command to allow ease of directory changes.
- *
- * MODIFICATION HISTORY
- *
- * 8/2/91 Sunil William Savkar
- * Changed code to allow running on HPs.
- *
- * 12/6/92 Sunil William Savkar
- * Changed code to allow for alphabetical sorting
- * of the mark file (easier to peruse).
- *
- * Please send all updates along with suggestions
- * to sunil@hal.com
- */
-
- #if (MACH == hp || MACH == m88k || MACH == rs)
- #include <stdlib.h>
- #else
- #include <alloca.h>
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include "macros.h"
- #include "enum.h"
- #include "types.h"
-
-
- /*
- * command[]
- *
- * This array holds all the strings which are command line arguments
- * recognized, along with the enumerated type they match with.
- */
-
- COMMAND_NODE command[] = { K_MARK_DIR, "", K_REMOVE_MARK, "-rm",
- K_HELP, "-h", K_HELP, "-help", K_VERSION,
- "-v", K_VERSION, "-ver", K_VERSION, "version",
- K_RESET_MARKS, "-reset", K_REMOVE_MARK, "-remove",
- K_LIST_MARKS, "-list", K_REFRESH_MARKS, "-r",
- K_LIST_MARKS, "-l",
- K_REFRESH_MARKS, "-refresh", K_REFRESH_MARKS, "-ref",
- K_NULL, NULL};
-
- /*
- * version_header[]
- */
-
- static char version_header[] =
- "Mark Directory\tv1.7\tSunil William Savkar\n";
-
- /*
- * help_header[]
- */
-
- static char help_header[] =
- "Mark Directory\tv1.7\nusage:\tmark <options>\n\n\
- option\t\t\tdescription\n\n\
- <cr>\n\
- -l<ist>\t\t\tLists current marks and their directories\n\
- [mark]\t\t\tAliases current directory to alphanumeric mark name\n\
- -rm [mark]\n\
- -remove [mark]\t\tRemoves specified mark\n\
- -v<ersion>\t\tPrints current version of the program\n\
- -h<elp>\t\t\tThis help message\n\
- -reset\t\t\tClears all marks in the current environment\n\
- -r<efresh>\t\tRefreshes all marks in the current environment\n\
- \nexamples:\tmark xxx, mark -list, mark -reset, mark -rm xxx\n";
-
- /*
- * boolean read_into_list( char *mark_fil,
- * LIST_NODE **list_head)
- *
- * This routine opens the passed mark file, holding all the currently
- * enabled marks, and parses them into the linked list of marks
- * with their expansions.
- */
-
- boolean read_into_list(mark_fil, /* The mark file */
- list_head, /* Pointer to the head of the mark list */
- list_tail)
- char *mark_fil;
- LIST_NODE **list_head;
- LIST_NODE **list_tail;
- {
-
- FILE *mark_fp; /* Pointer to the mark file stream */
- LIST_NODE *new_ptr; /* New list element to add to marks */
- char setenv[MAX_LINE]; /* Contains the setenv line in mark file */
- char mark[MAX_LINE]; /* The mark string which will expand */
- char path[MAX_LINE]; /* The expansion of the mark */
- char buffer[MAX_LINE]; /* Temporary buffer to hold information */
-
- /*
- * Open the mark file.
- */
-
- *list_tail = *list_head;
- if (!(mark_fp = fopen(mark_fil, "r"))) {
-
- fprintf(stderr, "read_into_list: Unable to open %s\n", mark_fil);
- return FALSE;
- }
-
- /*
- * Now continue reading the file and setting up the linked list.
- */
-
- while (fgets(buffer, MAX_LINE, mark_fp)) {
-
- /*
- * Format for the file is : "setenv mark_<mark_name> <mark_expansion>"
- */
-
- sscanf(buffer, "%s mark_%s %s", setenv, mark, path);
-
- if (STREQU(setenv, "unsetenv")) continue;
- if (!STREQU(setenv, "setenv")) {
-
- fprintf(stderr, "read_into_list: Error in mark database\n");
- return FALSE;
- }
-
- /*
- * Set up a new node.
- */
-
- if (!(new_ptr = (LIST_NODE *)malloc(sizeof(LIST_NODE)))) {
-
- fprintf( stderr, "read_into_list: error mallocing new structure\n");
- return FALSE;
- }
-
- new_ptr->unset_flag = FALSE;
- if (!(new_ptr->mark = (char *)malloc(strlen(mark) + 1))) {
-
- fprintf( stderr, "read_into_list: error mallocing new mark string\n");
- return FALSE;
- } else if (!(new_ptr->path = (char *)malloc(strlen(path) + 1))) {
-
- fprintf( stderr, "read_into_list: error mallocing new expand string\n");
- return FALSE;
- }
- new_ptr->next = NULL;
- strcpy(new_ptr->mark, mark); strcpy(new_ptr->path, path);
-
- /*
- * Insert the new mark into the list.
- */
-
- if (*list_head == NULL) {
-
- *list_head = *list_tail = new_ptr;
- } else {
-
- (*list_tail)->next = new_ptr;
- *list_tail = new_ptr;
- }
- }
-
- /*
- * Done with generating the linked list of current marks.
- */
-
- fclose(mark_fp);
- return TRUE;
- }
-
- /*
- * boolean initialize( char **pwd,
- * char *mark_fil,
- * LIST_NODE **list_head,
- * LIST_NODE **list_tail)
- *
- * This routine is called to initialize the variables and list
- * of marks currently set.
- */
-
- boolean initialize( pwd,
- mark_fil,
- list_head,
- list_tail)
- LIST_NODE **list_tail;
- LIST_NODE **list_head;
- char *mark_fil;
- char **pwd;
- {
-
- FILE *mark_fp;
- char *getenv();
- char *ptr;
-
- /*
- * Get current directory and pointer to the mark directory.
- */
-
- #ifdef HP
-
- if (!(getcwd((*pwd = (char *)malloc(MAX_LINE)), MAX_LINE))) {
- #else
-
- if (!(*pwd = getenv("PWD"))) {
- #endif
-
- fprintf(stderr, "initialize: Unable to get environment var $PWD\n");
- return FALSE;
- }
-
- /*
- * Notice we would like to strip off the /tmp_mount from the *pwd,
- * if it exists!
- */
-
- if (strncmp(*pwd, "/tmp_mnt", 8) == 0) {
- *pwd += 8;
- }
-
- if (!(ptr = getenv("MARK_DIR"))) {
-
- fprintf(stderr, "initialize: Must set environment var $MARK_DIR\n");
- return FALSE;
- } else {
-
- /*
- * Construct mark data base file pointer.
- */
-
- sprintf( mark_fil, "%s/mark_db", ptr);
- }
-
- if (!(mark_fp = fopen(mark_fil, "a"))) {
-
- fprintf(stderr, "initialize: Unable to open %s\n", mark_fil);
- return FALSE;
- }
-
- fclose(mark_fp);
-
- /*
- * Read marks into a linked list, with the mark string,
- * and the path string.
- */
-
- if (!read_into_list(mark_fil, list_head, list_tail)) {
-
- fprintf(stderr, "initialize: Unable to read mark file %s\n", mark_fil);
- return FALSE;
- }
-
- return TRUE;
- }
-
- /*
- * T_COMM parse( char *option)
- *
- * This routine returns the enumeration for the given string which
- * represents an option on the command line. Options can be anything
- * from -help for help, to the mark to be set.
- */
-
- T_COMM parse( option) /* The string representing the option requested */
- char *option;
- {
-
- int j;
- char *ptr;
-
- /*
- * No dash indicates no real option, but just a directory to mark.
- */
-
- if (*option != '-') {
-
- return K_MARK_DIR;
- }
-
- /*
- * Must be one of the commands, else there is
- * an error.
- */
-
- for (j = 0; ptr = command[j].text; j++) {
-
- if (STREQU(ptr, option)) break;
- }
-
- if (!ptr) {
-
- fprintf(stderr, "parse: unrecognized option from main (%s)\n", option);
- return K_NULL;
- }
-
- return command[j].type;
- }
-
- boolean list_marks( list_ptr)
- LIST_NODE *list_ptr;
- {
-
-
- /*
- * Each line consists of the mark, and then the pathname.
- */
-
- fprintf(stdout, "MARK\t\tPATH\n----\t\t----\n");
- for (; list_ptr; list_ptr = list_ptr->next) {
-
- fprintf(stdout, "%s\t\t%s\n", list_ptr->mark, list_ptr->path);
- }
-
- return TRUE;
- }
-
- /*
- * boolean mark_dir( char *pwd,
- * char *mark,
- * LIST_NODE **list_head,
- * LIST_NODE **list_tail)
- *
- * This routine adds a new mark with expansion to the given list.
- */
-
- boolean mark_dir(pwd,
- mark,
- list_head,
- list_tail)
- LIST_NODE **list_head,
- **list_tail;
- char *pwd;
- char *mark;
- {
-
- char *ptr;
- LIST_NODE *new_ptr, *list_ptr;
-
- /*
- * A mark must be alphanumeric.
- */
-
- for (ptr = mark; *ptr != '\0'; ptr++) {
-
- if (!(isalnum(*ptr) || (*ptr == '_'))) {
-
- fprintf(stderr, "mark_dir: mark must be alphanumeric\n");
- return FALSE;
- }
- }
-
- /*
- * If there is an old mark by the same name, just change the
- * path for that mark.
- */
-
- for (list_ptr = *list_head; list_ptr; list_ptr = list_ptr->next) {
-
- if (STREQU(mark, list_ptr->mark)) break;
- }
-
- if (list_ptr) {
-
- free(list_ptr->path);
- list_ptr->path = pwd;
- } else if (!(new_ptr = (LIST_NODE *)malloc(sizeof(LIST_NODE)))) {
-
- fprintf(stderr, "mark_dir: error allocating space in list\n");
- return FALSE;
- } else {
-
- new_ptr->unset_flag = FALSE;
- new_ptr->next = NULL;
- new_ptr->mark = mark;
- new_ptr->path = pwd;
-
- if (*list_head == NULL) {
-
- *list_head = *list_tail = new_ptr;
- } else {
-
- (*list_tail)->next = new_ptr;
- *list_tail = new_ptr;
- }
- }
-
- fprintf(stderr, "mark_dir: mark \"%s\" (%s) set\n", mark, pwd);
- return TRUE;
- }
-
- /*
- * boolean remove_mark( char *mark,
- * LIST_NODE *list_ptr)
- *
- * This routine is used to remove a mark from the given list (through
- * including an unsetenv declarator in the mark file.
- */
-
- boolean remove_mark(mark,
- list_ptr)
- char *mark;
- LIST_NODE *list_ptr;
- {
-
- for (; list_ptr; list_ptr = list_ptr->next) {
-
- if (STREQU(list_ptr->mark, mark)) {
-
- list_ptr->unset_flag = TRUE;
- fprintf( stderr, "mark_dir: mark \"%s\" (%s) removed\n", mark,
- list_ptr->path);
- return TRUE;
- }
- }
-
- fprintf(stderr, "mark_dir: mark \"%s\" not found\n", mark);
- return FALSE;
- }
-
- /*
- * boolean reset_marks( LIST_NODE *list_ptr)
- *
- * This routine resets the marks by unsetenv all of them.
- */
-
- boolean reset_marks( list_ptr)
- LIST_NODE *list_ptr;
- {
-
- /*
- * Go through all the marks and set their unset_flag.
- */
-
- for (; list_ptr; list_ptr = list_ptr->next) list_ptr->unset_flag = TRUE;
-
- return TRUE;
- }
-
- /*
- * boolean sort_list( list_head)
- *
- * This routine simply pops off the old list and rearranges into a sorted
- * order. This simple routine is written instead of using the system
- * sort command.
- */
-
- void sort_list( list_head)
- LIST_NODE **list_head;
- {
-
- LIST_NODE *sort_head,
- *sort_tail,
- *list_ptr,
- *old_ptr,
- *sort_ptr;
-
- sort_head = old_ptr = NULL;
-
- /*
- * Pop off the old list and rearrange in the new sort list.
- */
-
- while (*list_head) {
-
- list_ptr = *list_head;
- *list_head = (*list_head)->next;
- list_ptr->next = NULL;
-
- /*
- * No sorted list exists.
- */
-
- if (!sort_head) {
-
- sort_head = sort_tail = list_ptr;
- continue;
- } else {
-
- /*
- * Check for mark precedence over current list head.
- */
-
- if (strcmp( list_ptr->mark, sort_head->mark) < 0) {
-
- list_ptr->next = sort_head;
- sort_head = list_ptr;
-
- /*
- * Check for mark being of lesser precedence than the tail.
- */
-
- } else if (strcmp( list_ptr->mark, sort_tail->mark) > 0) {
-
- sort_tail->next = list_ptr;
- sort_tail = list_ptr;
- } else {
-
- /*
- * Insert the mark somewhere within the list alphabetically.
- */
-
- for (sort_ptr = sort_head; sort_ptr; old_ptr = sort_ptr, sort_ptr = sort_ptr->next) {
-
- if (strcmp( list_ptr->mark, sort_ptr->mark) < 0) {
-
- old_ptr->next = list_ptr;
- list_ptr->next = sort_ptr;
- break;
- }
- }
- }
- }
- }
-
- /*
- * Set the new list head.
- */
-
- *list_head = sort_head;
- }
-
- boolean update_file( mark_fil, list_ptr)
- char *mark_fil;
- LIST_NODE *list_ptr;
- {
-
- FILE *mark_fp;
-
- /*
- * Write the new list of marks to the update file.
- */
-
- if (!(mark_fp = fopen(mark_fil, "w"))) {
-
- fprintf(stderr, "update_file: Unable to update %s\n", mark_fil);
- return FALSE;
- }
-
- for (; list_ptr; list_ptr = list_ptr->next) {
-
- if (!list_ptr->unset_flag) {
-
- fprintf(mark_fp, "setenv mark_%s %s\n", list_ptr->mark, list_ptr->path);
- } else {
-
- fprintf(mark_fp, "unsetenv mark_%s\n", list_ptr->mark);
- }
- }
-
- fclose(mark_fp);
- return TRUE;
- }
-
- /*
- * main( int argc,
- * char *argv[])
- *
- * The main event.
- */
-
- main(argc,
- argv)
- char *argv[];
- int argc;
- {
-
- LIST_NODE *list_head,
- *list_tail;
- int i;
- char mark_fil[MAX_LINE];
- char *pwd;
- T_COMM option;
-
- list_head = list_tail = NULL;
-
- /*
- * First we must initialize, getting pointer to the
- * mark file, and read in the current directory.
- */
-
- if (!initialize(&pwd, mark_fil, &list_head, &list_tail)) {
-
- fprintf(stderr, "mark: error code from initialize\n");
- exit(-1);
- }
-
- /*
- * Now we have the file pointer for mark, and the current
- * directory. It is time to start parsing the arguments
- * on the command line.
- */
-
- for (i = 1; i <= argc; i++) {
-
- if (argc == 1) {
-
- option = K_LIST_MARKS;
- } else if (i == argc) {
-
- break;
- } else if ((option = parse( argv[i])) == K_NULL) {
-
-
- fprintf(stderr, "mark: error code from parse\n");
- exit(-1);
- }
-
- /*
- * Switch, based upon the given option, to the
- * proper function.
- */
-
- switch (option) {
-
- case K_MARK_DIR:
-
- if (!mark_dir(pwd, argv[i], &list_head, &list_tail)) {
-
- fprintf(stderr, "mark: error code from mark_dir\n");
- exit(-1);
- }
- break;
-
- case K_REMOVE_MARK:
- if (!remove_mark(argv[++i], list_head)) {
-
- fprintf(stderr, "mark: error code from remove_mark\n");
- exit(-1);
- }
- break;
-
- case K_LIST_MARKS:
- if (!list_marks(list_head)) {
-
- fprintf(stderr, "mark: error code from list_marks\n");
- exit(-1);
- }
- break;
-
- case K_VERSION:
- fprintf(stdout, version_header);
- break;
-
- case K_HELP:
- fprintf(stdout, help_header);
- break;
-
- case K_RESET_MARKS:
- if (!reset_marks(list_head)) {
-
- fprintf(stderr, "mark: error code from reset_marks\n");
- exit(-1);
- }
- break;
-
- case K_REFRESH_MARKS: break;
- default: break;
- }
- }
-
- if (option == K_MARK_DIR) sort_list( &list_head);
- if (!update_file(mark_fil, list_head)) {
-
- fprintf(stderr, "mark: error code from update_file\n");
- exit(-1);
- }
-
- exit(0);
- }
-