home *** CD-ROM | disk | FTP | other *** search
- /* dirList.c
- routines to manage the data structures for gopher directories */
-
- /*---------------------------------------------------------------*/
- /* Xgopher version 1.3 08 April 1993 */
- /* version 1.2 20 November 1992 */
- /* version 1.1 20 April 1992 */
- /* version 1.0 04 March 1992 */
- /* X window system client for the University of Minnesota */
- /* Internet Gopher System. */
- /* Allan Tuchman, University of Illinois at Urbana-Champaign */
- /* Computing and Communications Services Office */
- /* Copyright 1992, 1993 by */
- /* the Board of Trustees of the University of Illinois */
- /* Permission is granted to freely copy and redistribute this */
- /* software with the copyright notice intact. */
- /*---------------------------------------------------------------*/
-
-
-
- #include <stdio.h>
-
- #include "gopher.h"
- #include "dirList.h"
- #include "item.h"
- #include "listP.h"
-
- #include "osdep.h"
-
- static gopherDirList unusedDirs = {NULL, NULL};
-
- static int firstDirAlloc = TRUE;
-
-
- /* Directory list management routines:
- acquireDir() return ptr to a gopherDir structure
- releaseDir(gopherDirP) Return directory to the free list
- previousDir(gopherDirP) return a pointer to previous directory
- nextDir(gopherDirP) return a pointer to next directory
- freeDirList(gopherDirP) Free a list of directories
- allocGopherDir(int) Allocate n new gopher directories
-
- current directory list management:
- getCurrentDir() return a ptr to current directory
- pushCurrentDir(gopherDirP) Push a new directory to be current
- popCurrentDir() make previous directory current
- getCurrentDirIndex() return search string of curr directory
- noCurrentDir() T/F; does current directory exist
- atFirstDir() T/F; is current directory first one
- checkDirStack() freeing expired gopher items from stack
- */
-
-
- /* acquireDir
- Allocate a gopher directory from the free list */
-
- gopherDirP
- acquireDir()
- {
- gopherDirP dir;
-
- if (unusedDirs.first == NULL) {
- /* out of gopher directories, so allocate more */
- allocGopherDir(firstDirAlloc ? dirStart : dirIncrement);
- firstDirAlloc = FALSE;
- }
- dir = unusedDirs.first;
- unusedDirs.first = dir->next;
- if (unusedDirs.first == NULL) unusedDirs.last = NULL;
-
- dir->previous = dir->next = NULL;
-
- return dir;
- }
-
-
- /* releaseDir
- Return a gopher directory to the free list */
-
- void
- releaseDir(dir)
- gopherDirP dir;
- {
- dir->next = unusedDirs.first;
- unusedDirs.first = dir;
- if (unusedDirs.last == NULL) unusedDirs.last = dir;
-
- return;
- }
-
-
- /* previousDir
- return a pointer to the directory previous to the given one */
-
- gopherDirP
- previousDir(dir)
- gopherDirP dir;
- {
- if (dir == NULL) return NULL;
- return dir->previous;
- }
-
-
- /* nextDir
- return a pointer to the directory following to the given one*/
-
- gopherDirP
- nextDir(dir)
- gopherDirP dir;
- {
- if (dir == NULL) return NULL;
- return dir->next;
- }
-
-
- /* freeDirList
- Free a list of directories */
-
- static void
- freeDirList(dir)
- gopherDirP dir;
- {
- gopherDirP p;
-
- for (p=dir; p->next != NULL; p=p->next) ;
-
- if (unusedDirs.last == NULL) unusedDirs.last = p;
- p->next = unusedDirs.first;
- unusedDirs.first = dir;
-
- return;
- }
-
-
- /* allocGopherDir
- Allocate n new gopher directories, adding them to the free list */
-
- static void
- allocGopherDir(n)
- int n;
- {
- gopherDirP dirList, p;
- int i;
-
- if (n <= 0) return;
-
- if ((dirList = (gopherDirP) malloc(n * sizeof(gopherDir))) == NULL) {
- /* out of memory */
- fprintf (stderr, "There is not enough memory to continue.\n");
- exit(3);
- }
-
- for (i=0, p=dirList; i<n-1; i++, p++) {
- p->next = p+1;
- }
- p->next = NULL;
- freeDirList(dirList);
-
- return;
- }
-
- /* -----------------------------------------------------------------------
- Special section for managing Current directory and the directory stack
- ----------------------------------------------------------------------- */
-
- static gopherDirP currentDir = NULL; /* current directory pointer */
- static gopherDirP firstDir = NULL; /* start of dir stack */
-
-
- /* getCurrentDir
- return a pointer to the current directory */
-
- gopherDirP
- getCurrentDir()
- {
- return currentDir;
- }
-
-
- /* pushCurrentDir
- Push a new directory to the stack after the current one and
- make the new one current. */
-
- void
- pushCurrentDir(dir)
- gopherDirP dir;
- {
-
- /* check for first directory in stack */
-
- if (currentDir == NULL) {
- dir->previous = NULL;
- firstDir = dir;
- } else {
-
- /* discard "popped" directories, if any */
-
- reallyPopFrom(currentDir->next);
-
- dir->previous = currentDir;
- currentDir->next = dir;
- }
-
- dir->next = NULL;
- currentDir = dir;
-
- return;
- }
-
-
- /* popCurrentDir
- Just move back to previous directory. Don't actually
- delete the subsequent ones until a new push is done. */
-
- void
- popCurrentDir()
- {
- if (currentDir == NULL) return;
- if (currentDir->previous == NULL) return;
-
- currentDir = currentDir->previous;
-
- return;
- }
-
-
- /* reallyPopFrom
- discard and reclaim the directories in the stack starting from
- the given one */
-
- static void
- reallyPopFrom(d)
- gopherDirP d;
- {
- gopherDirP tmp;
-
- while (d != NULL){
- tmp = d->next;
- freeDir(d);
- d = tmp;
- }
- }
-
-
- /* getCurrentDirIndex
- return a pointer to the index search string of the current directory */
-
- char *
- getCurrentDirIndex()
- {
- return getItemIndex(currentDir->selectorItem);
- }
-
-
- /* atFirstDir
- return TRUE is current directory is the first one, FALSE otherwise */
-
- BOOLEAN
- atFirstDir()
- {
- return ((currentDir == NULL) || (currentDir->previous == NULL));
- }
-
-
- /* noCurrentDir
- return TRUE is there is no current directory, yet; FALSE otherwise */
-
- BOOLEAN
- noCurrentDir()
- {
- return (currentDir == NULL);
- }
-
-
- /* clearDirStack
- wipe out the cirectory stack; set it back to its initial state */
-
- void
- clearDirStack()
- {
- reallyPopFrom(firstDir);
- currentDir = NULL;
- firstDir = NULL;
- }
-
-
- /* checkDirStack
- traverse directory stack freeing expired gopher items */
-
- void
- checkDirStack()
- {
- gopherDirP d;
-
- for (d=firstDir; d != NULL; d = d->next) {
- if (d->created != NOT_LOADED) clearDirWhenOld(d);
- }
-
- return;
- }
-