This is futil.c in view mode; [Download] [Up]
/* Wide AREA INFORMATION SERVER SOFTWARE No guarantees or restrictions. See the readme file for the full standard disclaimer. 3/90 Brewster */ /* Change log: * $Log: futil.c,v $ * Revision 1.21 92/03/24 10:30:41 jonathan * Added fix to pathname_directory if no directory part, it puts "./" in the * destination. * * Revision 1.20 92/02/21 11:05:48 jonathan * added RCSIdent * * Revision 1.19 92/02/20 14:51:19 jonathan * changed include for access() to sys/file.h, since that seems more portable. * * Revision 1.18 92/02/18 11:52:43 jonathan * conditionalized inclusion of unistd.h for NeXT (use fcntl instead). This * may be a BSD thing. * * Revision 1.17 92/02/12 13:19:27 jonathan * Added "$Log" so RCS will put the log message in the header * */ #ifndef lint static char *RCSid = "$Header: /tmp_mnt/net/quake/proj/wais/wais-8-b5/ir/RCS/futil.c,v 1.21 92/03/24 10:30:41 jonathan Exp $"; #endif /* ======================== */ /* === File Utilities === */ /* ======================== */ #include <string.h> #ifdef THINK_C /* file type info */ #include <pascal.h> /* for CtoPstr */ #include <FileMgr.h> #define CREATOR 'WIS1' #define WAIS_INDEX_FILE_TYPE 'INDX' #else #include <sys/types.h> /* for stat and getuid */ #include <sys/stat.h> /* for stat */ #include <sys/param.h> /* for getwd */ /* for access() */ #include <sys/file.h> #endif /* THINK_C */ #include "futil.h" #include "panic.h" /*----------------------------------------------------------------------*/ static long numFilesCurrentlyOpen = 0; static long maxNumFilesOpenAtOneTime = 0; FILE* fs_fopen(fileName,mode) char* fileName; char* mode; { FILE* file = NULL; char realMode[100]; #ifdef BSD #define implicitBinary #endif /* def BSD */ #ifdef ultrix #define implicitBinary #endif /* def ultrix */ #ifndef ANSI_LIKE #define implicitBinary #endif /* def ANSI_LIKE */ #ifdef implicitBinary /* these old os's don't handle the binary mode. Just remove it */ long i,j; for (i = 0L,j = 0; mode[i] != '\0';i++) { if (mode[i] != 'b') realMode[j++] = mode[i]; } realMode[j] = '\0'; file = fopen(fileName,realMode); #else file = fopen(fileName,mode); #endif /* def implicitBinary */ if (file != NULL) { numFilesCurrentlyOpen++; if (numFilesCurrentlyOpen > maxNumFilesOpenAtOneTime) maxNumFilesOpenAtOneTime = numFilesCurrentlyOpen; } return(file); } /*----------------------------------------------------------------------*/ long fs_fclose(file) FILE* file; { if (file != NULL) { numFilesCurrentlyOpen--; return(fclose(file)); } else return(0L); } /*----------------------------------------------------------------------*/ long fs_fseek(file,offset,wherefrom) FILE* file; long offset; long wherefrom; { long result; if(NULL == file) return -1; result = fseek(file, offset, wherefrom); /* if(0 != result) panic("A seek failed: offset %ld, wherefrom %d.\n",offset, wherefrom); */ return result; } /*----------------------------------------------------------------------*/ long fs_ftell(file) FILE* file; { long result; if (file == NULL) return(0); result = ftell(file); if(EOF == result) panic("A seek on an index file failed.\n"); return(result); } /*----------------------------------------------------------------------*/ void grow_file(file,length) FILE* file; long length; { long current_length; s_fseek(file, 0L, SEEK_END); current_length = s_ftell(file); s_fseek(file, length - current_length, SEEK_END); } /*----------------------------------------------------------------------*/ /* writes the high byte first, this makes reading faster */ long write_bytes(value,size,stream) long value; long size; FILE* stream; { long i; long answer; if((size < sizeof(long)) && (0 != (value >> (size * 8)))) panic("In a call to write_bytes, the value %ld can not be represented in %ld bytes", value, size); for(i = size - 1; i >= 0; i--){ answer = putc((value >> (i * 8)) & 0xFF, stream); } if(ferror(stream) != 0) { panic("Write failed"); } return(answer); } /*----------------------------------------------------------------------*/ /* returns EOF if it gets an error */ long read_bytes(n_bytes,stream) long n_bytes; FILE *stream; { long answer = 0; unsigned long ch; long i; for(i = 0; i < n_bytes; i++){ ch = fgetc(stream); if(EOF == ch){ return(EOF); } answer = (answer << 8) + (unsigned char)ch; } return(answer); } /*----------------------------------------------------------------------*/ long read_bytes_from_memory(n_bytes,block) long n_bytes; unsigned char *block; { long answer = 0; unsigned char ch; long i; for(i = 0; i < n_bytes; i++){ ch = *(block++); answer = (answer << 8) + ch; } return(answer); } /*----------------------------------------------------------------------*/ time_t file_write_date(filename) char* filename; { /* os dependent */ #ifdef THINK_C return((time_t)0); /* not implemented yet */ #else struct stat *buf = (struct stat*)s_malloc((size_t)sizeof(struct stat)); time_t mtime; if(0 != stat(filename, buf)){ panic("could not stat %s", filename); } mtime = buf->st_mtime; s_free(buf); return(mtime); #endif /* THINK_C */ } /*----------------------------------------------------------------------*/ long file_length(stream) FILE* stream; /* return the length (in bytes) of a stream - leave the current position where it was */ { long position = ftell(stream); long end = -1; s_fseek(stream, 0L, SEEK_END); end = ftell(stream); s_fseek(stream,position,SEEK_SET); return(end); } /*----------------------------------------------------------------------*/ static char *clean_path _AP((char* filename)); static char *clean_path(filename) char *filename; /* this takes out the '/../' and the '/./' from the path by modifying the argument and returning it. The pathname passed to it must be a full path. This is not optimized. */ { #ifndef THINK_C char *beginning_ptr = strstr(filename, "/../"); if(NULL != beginning_ptr){ /* then we have something to process. reverse search for the beginning of the last directory, in order to snuff it */ char *ptr; for(ptr = beginning_ptr - 1; ptr >= filename; ptr--){ if(*ptr == '/'){ /* then we found the beginning of the path */ strcpy(ptr, beginning_ptr + strlen("/../") -1); clean_path(filename); /* get the other occurances of /../ */ break; } } } /* now look for /./ */ beginning_ptr = strstr(filename, "/./"); if(NULL != beginning_ptr){ strcpy(beginning_ptr, beginning_ptr + strlen("/./") -1); clean_path(filename); /* get the other occurances of /./ */ } #endif /* ndef THINK_C */ return(filename); } /*----------------------------------------------------------------------*/ char *truename(filename,full_path) char *filename; char *full_path; { /* this puts into full_path the full pathname including directory. */ #ifdef THINK_C strcpy(full_path, filename); return(full_path); /* do nothing */ #else if('/' == filename[0]){ /* then it is complete already */ strcpy(full_path, filename); clean_path(full_path); return(full_path); } else{ getwd(full_path); s_strncat(full_path,"/",MAX_FILENAME_LEN,MAX_FILENAME_LEN); s_strncat(full_path,filename,MAX_FILENAME_LEN,MAX_FILENAME_LEN); clean_path(full_path); return(full_path); } #endif /* THINK_C */ } /*----------------------------------------------------------------------*/ char *pathname_name(pathname) char *pathname; /* returns a pointer to the leaf name part of full pathname. equivalent to common lisp pathname-name. */ { #ifdef THINK_C char *answer = strrchr(pathname, ':'); #else char *answer = strrchr(pathname, '/'); #endif /* THINK_C */ if(NULL == answer) return(pathname); return(answer + 1); } /*----------------------------------------------------------------------*/ char *pathname_directory(pathname,destination) char *pathname; char *destination; /* returns a pointer to a string of the directory part of the pathname and modifies its destination argument. This is the equivalent to the common lisp pathname-directory function. */ { #ifdef THINK_C char *dirptr = strrchr(pathname, ':'); #else char *dirptr = strrchr(pathname, '/'); #endif /* THINK_C */ if(NULL == dirptr) #ifdef THINK_C strncpy(destination, pathname, MAX_FILE_NAME_LEN); #else strncpy(destination, "./", MAX_FILENAME_LEN); #endif /* THINK_C */ else { strncpy(destination, pathname, MAX_FILE_NAME_LEN); destination[dirptr - pathname + 1] = '\0'; } return(destination); } /*----------------------------------------------------------------------*/ /* Setting the Macintosh File type (requires the MacTraps library) */ /* from Util.c by Harry Morris */ #ifdef THINK_C void setFileType(fileName,type,creator) char* fileName; FType type; FType creator; { FInfo info; OSErr error; CtoPstr(fileName); error = GetFInfo((StringPtr)fileName,0L,&info); if (error != noErr) panic("error - Can't get file type of file %s, code %ld\n", PtoCstr((char*)fileName),noErr); info.fdType = type; info.fdCreator = creator; error = SetFInfo((StringPtr)fileName,0L,&info); if (error != noErr) panic("error - Can't change file type of file %s, code %ld\n", PtoCstr((char*)fileName),noErr); PtoCstr((char*)fileName); } #endif /* THINK_C */ /*----------------------------------------------------------------------*/ char *current_user_name() /* returns the current_user_name as a mail address */ { static char answer[200]; char hostname[120]; #ifdef THINK_C strcpy(answer,"MAC"); /* could look up the name in the chooser */ #endif /* def THINK_C */ #ifdef M_XENIX strcpy(answer,"unknown"); /* could look up the name in the chooser */ #endif /* def M_XENIX */ #ifndef THINK_C #ifndef M_XENIX #include <pwd.h> /* for getpwent */ struct passwd *pwent = getpwuid(getuid()); strncpy(answer, pwent->pw_name, 200); strncat(answer, "@", 200); gethostname(hostname, 120); strncat(answer, hostname, 200); #endif /* ndef M_XENIX */ #endif /* ndef THINK_C */ return(answer); } /*----------------------------------------------------------------------*/ boolean probe_file(filename) char *filename; /* return true if it is there, false otherwise. Can this be done faster? */ { if (filename == NULL) return(false); else if (access(filename,R_OK) == 0) return(true); else return(false); } /*----------------------------------------------------------------------*/ boolean probe_file_possibly_compressed(filename) char *filename; /* return true if it is there, false otherwise. Can this be done faster? */ { if (filename == NULL) return(false); else if (!probe_file(filename)) { /* try the compression */ char buffer[ MAX_FILENAME_LEN * 2 ]; strcpy(buffer, filename); strcat(buffer, ".Z"); return(probe_file(buffer)); } else return(true); } /*----------------------------------------------------------------------*/ /* this opens the file for writing (append)p and then closes it again */ boolean touch_file(filename) char *filename; /* return false if error, true otherwise. */ { FILE *stream = NULL; if (filename == NULL) return(false); stream = s_fopen(filename, "a"); if (NULL == stream) return(false); else { s_fclose(stream); return(true); } } /*----------------------------------------------------------------------*/ char *merge_pathnames(pathname, directory) char *pathname; char *directory; { /* if the pathname is not complete, then it puts on the directory component and returns it in a static variable. This is Unix specific */ static char answer[MAX_FILENAME_LEN + 1]; if((pathname[0] == '/') || (NULL == directory) || directory[0] == '\0') return(pathname); else{ answer[0] = '\0'; strncat(answer, directory, MAX_FILENAME_LEN); #ifdef THINK_C if(directory[strlen(directory) - 1] != ':') strncat(answer, ":", MAX_FILENAME_LEN); #else if(directory[strlen(directory) - 1] != '/') strncat(answer, "/", MAX_FILENAME_LEN); #endif strncat(answer, pathname, MAX_FILENAME_LEN); } /* should this call truename? */ return(answer); } /*----------------------------------------------------------------------*/ boolean read_string_from_file(stream,array,array_length) FILE *stream; char *array; long array_length; /* returns true if it wins. */ { long ch; long char_count = 0; array[0] = '\0'; while(true){ ch = fgetc(stream); if(EOF == ch){ array[char_count] = '\0'; return(false); } else if(char_count == array_length){ array[char_count] = '\0'; return(false); } else if('\0' == ch){ array[char_count] = '\0'; return(true); } else array[char_count++] = ch; } } /* counts the lines in a file */ long count_lines(stream) FILE *stream; { long answer = 1; char line[100]; fseek(stream, 0L, SEEK_SET); while(NULL != fgets(line,100L,stream)) answer++; return(answer); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.