home *** CD-ROM | disk | FTP | other *** search
- /* misc.c
- miscellaneous utility functions. */
-
- /*---------------------------------------------------------------*/
- /* 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 <sys/time.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- #include "conf.h"
- #include "gopher.h"
- #include "globals.h"
- #include "appres.h"
- #include "itemList.h"
- #include "dirList.h"
- #include "misc.h"
-
- #include "osdep.h"
-
-
- /* timeNow
- return the current time in some useful units, e.g., seconds. */
-
- gopherTime
- timeNow()
- {
- struct timeval tp;
- struct timezone tzp;
-
- gettimeofday(&tp, &tzp);
- return tp.tv_sec;
- }
-
-
-
- /* timeSince
- return the units (e.g., seconds) of time elapsed since the given time. */
-
- gopherTime
- timeSince(t)
- gopherTime t;
- {
- struct timeval tp;
- struct timezone tzp;
-
- return (timeNow() - t);
- }
-
-
- /* setDirTime
- set the creation time field on a gopher directory */
-
- void
- setDirTime(d)
- gopherDirP d;
- {
- d->created = timeNow();
- return;
- }
-
-
- /* clearDirWhenOld
- cause a directory to be updated if it's creation time was a while ago. */
-
- void
- clearDirWhenOld(d)
- gopherDirP d;
- {
- if (d == NULL || d == getCurrentDir()) return;
-
- if (d->created == NOT_LOADED) return;
-
- if (timeSince(d->created) > appResources->directoryTime) {
- LOG(logFP, "Freeing old directory: %s\n",
- USER_STRING(d->selectorItem));
- freeItemList(&(d->contents));
- d->created = NOT_LOADED;
- }
-
- return;
- }
-
-
- /* getTempFile
- generate a temperary file name and return a pointer to it.
- The caller should check for a NULL file pointer.
- (The Unix routines mktemp(), tmpnam(), or tempnam() could be
- used as the body of this routine.) */
-
- void
- getTempFile(tempName)
- char *tempName;
- {
- static int fileCount = 0;
- static int thisPID = 0;
-
- if (thisPID == 0) thisPID = getpid();
- sprintf (tempName, "%s/gop%d.%d",
- tildePath(appResources->tempDirectory),
- thisPID, fileCount++);
-
- return;
- }
-
-
- /* These symbols are on most, but not all flavors of Unix, usually
- in <sys/stat.h> or <sys/mode.h>. They are defined here just in
- case they are missing. The symbols here are the POSIX names. */
-
- #ifndef S_IWUSR
- #ifdef S_IWRITE
- #define S_IWUSR S_IWRITE /* write permission, owner */
- #else /* !def S_IWRITE */
- #define S_IWUSR 0000200 /* write permission, owner */
- #endif /* def S_IWRITE */
- #endif
-
- #ifndef S_IWGRP
- #define S_IWGRP 0000020 /* write permission, group */
- #endif
-
- #ifndef S_IWOTH
- #define S_IWOTH 0000002 /* write permission, other */
- #endif
-
-
- /* isWriteableMode
- return true if the given path name is that of an writable directory */
-
- BOOLEAN
- isWriteableMode(statBuf)
- struct stat *statBuf;
- {
- int myUid, myGid;
-
- if (statBuf->st_mode & S_IWOTH) {
- return TRUE;
- }
-
- myGid = (int) getgid();
- if ((statBuf->st_gid == myGid) && (statBuf->st_mode & S_IWGRP)) {
- return TRUE;
- }
-
- myUid = (int) getuid();
- if (statBuf->st_uid == myUid && statBuf->st_mode & S_IWUSR) {
- return TRUE;
- }
-
- return FALSE;
- }
-
- /* These symbols are on most, but not all flavors of Unix, usually
- in <sys/stat.h>. They are defined here just in case they are missing.
- convex doesn't even have S_IEXEC. */
-
- #ifndef S_IEXEC
- #define S_IEXEC 0000100 /* execute/search permission, owner */
- #endif
-
- #ifndef S_IXGRP
- #define S_IXGRP 0000010 /* execute/search permission, group */
- #endif
-
- #ifndef S_IXOTH
- #define S_IXOTH 0000001 /* execute/search permission, other */
- #endif
-
-
- /* isExecutable
- return true if the given path name is that of an executable file */
-
- BOOLEAN
- isExecutable(pathName)
- char *pathName;
- {
- struct stat buf;
- int myUid, myGid;
-
- if (stat (pathName, &buf) != 0) return FALSE;
-
- if (buf.st_mode & S_IXOTH) {
- return TRUE;
- }
-
- myGid = (int) getgid();
- if ((buf.st_gid == myGid) && (buf.st_mode & S_IXGRP)) {
- return TRUE;
- }
-
- myUid = (int) getuid();
- if (buf.st_uid == myUid && buf.st_mode & S_IEXEC) {
- return TRUE;
- }
-
- return FALSE;
- }
-
-
- /* makeWordList
- turn a string of words into a list of words, ignoring reserved words. */
-
- char **
- makeWordList(string)
- char *string;
- {
- char *wordSpace;
- char **word;
- char *cp;
- char *wp;
- int next = 0;
- int n = 0;
-
- if (string == NULL) return NULL;
-
- if ( ((wordSpace = malloc(INDEX_WORD_LEN)) == NULL) ||
- ((word = (char **) malloc(INDEX_WORD_COUNT * sizeof(char *))) ==
- NULL) ) {
- fprintf(stderr,
- "Memory allocation error; trying to make index word list.\n");
- fprintf(stderr,
- "Recovery attempt by ignoring word list.\n");
- return NULL;
- }
-
- cp = string;
- while (*cp != '\0') {
- while ((! isalnum(*cp)) && *cp != '\0' ) cp++;
- if ( *cp == '\0' ) break;
- wp = word[n] = &(wordSpace[next]);
- while ( isalnum(*cp) ) {
- *wp++ = isupper(*cp) ? tolower(*cp) : *cp;
- cp++;
- }
- *wp = '\0';
-
- if ( strcmp( word[n], "and") == 0 ||
- strcmp(word[n], "not") == 0 ||
- strcmp(word[n], "or") == 0) {
- continue;
- }
-
- next = next + strlen( word[n]) + 1;
- n++;
- }
-
-
- if (n == 0) {
- free (wordSpace);
- free (word);
- return NULL;
- }
-
- word[n] = NULL;
- return (word);
- }
-
-
- /* freeWordList
- free a word list created by makeWordList. */
-
- void
- freeWordList(list)
- char **list;
- {
- if (list != NULL && list[0] != NULL) {
- free (list[0]);
- free (list);
- }
- }
-
-
- /* nextInPath
- is an auxiliary function to support cmdPath (below) */
-
- static char *
- nextInPath (scan)
- char **scan;
- {
- char *pc, *start;
-
- /*---Null scan pointer says we are done---*/
-
- if (*scan == 0) return(0);
-
- /*---Advance scan pointer until ':' or '\0'---*/
-
- for (pc=(*scan); (*pc != ':') &&
- (*pc != '\0'); pc++) ;
-
- /*---Remember where we started---*/
-
- start = *scan;
-
- /*---Did we get to the end of the path string?---*/
-
- if (*pc == '\0') {
- /*---Yes, tell the next time that we're done---*/
- *scan = 0;
- } else {
- /*---No, make the ':' into a NULL (terminates returned string)
- and advance next scan to char after ':'---*/
- *pc = '\0';
- *scan = pc+1;
- }
-
- return (start);
- }
-
-
- /* cmdPath
- this code finds the path to an executable program using the user's
- search path. If an absolute path name is provided, it is used.
- Otherwise, we use envp to find the $PATH environment
- variable; gets its value; then looks for the program name in
- that path. The absolute path name of the first executable program
- in the path is returned or NULL if none is found with execute
- permission.
-
- This routine is dependent on the Unix operating system. Mostly
- because the notion of what constitutes an executable file is
- OS specific. If you have porting problems, you can either rewrite
- this routine or just specify absolute path names everywhere. */
-
- char *
- cmdPath (pgmName)
- char *pgmName;
- {
- /* cmdPath uses stat(2) to look for the executable file by trying
- each directory in the users path. Each time that fails, try the
- next directory in the path. The first time it succeeds, return
- the path. If the name is not found at all in the path, then
- return NULL. */
-
- char path[PATH_NAME_LEN], tempbuf[PATH_NAME_LEN];
- char *scan, *dir;
- char *name, *pathVar;
- struct stat buf;
- char *absPathName = (char *) malloc (PATH_NAME_LEN);
-
- /* according to the man page for sh(1), if the command name
- contains a '/', then the $path variable is not searched. */
-
- if (index (pgmName, '/')) {
- strcpy (absPathName, pgmName);
- return (absPathName);
- } else {
- if (((pathVar = getenv ("PATH")) == NULL) ||
- (*pathVar == '\0')) {
- strcpy (absPathName, "./");
- strcat (absPathName, pgmName);
- return (absPathName);
- }
- strncpy (path, pathVar, PATH_NAME_LEN);
- *absPathName = '\0';
-
- scan = path;
-
- while( (dir = nextInPath (&scan)) != 0 ) {
- strncpy (tempbuf, dir, PATH_NAME_LEN);
- strcat (tempbuf, "/");
- name = strcat (tempbuf, pgmName);
-
- if (isExecutable(name)) {
- strcpy (absPathName, name);
- return (absPathName);
- }
- }
- return (NULL);
- }
- }
-
-
- #include <pwd.h>
- /* tildePath
- expand a leading "~/" on a pathname to be the value of $HOME/.
- The value returned is a pointer to static storage and must
- be copied by the caller to preserve it. If there is no leading "~/",
- then the input pathname is copied to the static storage. */
-
- char *
- tildePath(path)
- char *path;
- {
- char *home;
- static char newPath[PATH_NAME_LEN];
-
- *newPath = '\0';
-
- if (path != NULL) {
- if (*path == '~') {
- if (*(path+1) == '/' || *(path+1) == NULLC) {
- if ((home = getenv("HOME")) != NULL) {
- strcpy(newPath, home);
- }
- path++;
- } else {
- char *slash = index (path+1, '/');
- struct passwd *pwdentry;
- if (slash != NULL) {
- *slash = '\0';
- if ((pwdentry = getpwnam(path+1)) != NULL) {
- strcpy(newPath, pwdentry->pw_dir);
- path = slash;
- }
- *slash = '/';
- } else {
- if ((pwdentry = getpwnam(path+1)) != NULL) {
- strcpy(newPath, pwdentry->pw_dir);
- path += strlen(path);
- }
- }
- }
- }
- strcat(newPath, path);
- }
-
- return newPath;
- }
-
-
-
-
-
- /* vStringSet
- set the value of a variable length string, length and data.
-
- This routine was inspired by those in STRstring.* from the
- gopher Unix client, version 0.9. The main reason for changing
- them at all is that the chosen data type name in the original
- routines, String, conflicts with the X Window System data
- type of the same name, but different type.
-
- For our purposes it is not worth allocating less than 128
- bytes. The primary use is for selector strings. These will
- generally grow , but eventually stabalize around 100 bytes.
- Except for WAIS searches, when they will grow REALLY big. */
-
- void vStringSet(vs, value)
- vString *vs;
- char *value;
- {
- int need;
-
- if (value == NULL) return;
-
- if (*value == '\0')
- need = 1;
- else
- need = strlen(value) + 1;
-
- if (vs->data == NULL) {
- if (need < 128) need = 128;
- if ((vs->data = malloc (need * sizeof(char *))) == NULL) {
- fprintf (stderr,
- "Cannot allocate more memory for a string.");
- exit(1);
- }
- strcpy (vs->data, value);
- vs->len = need;
- } else {
- if (vs->len >= need)
- strcpy(vs->data, value);
- else {
- if ((vs->data = realloc(vs->data, need)) == NULL) {
- fprintf (stderr,
- "Cannot allocate more memory for a string.");
- exit(1);
- }
-
- strcpy(vs->data, value);
- vs->len = need;
- }
- }
- }
-