📄 escape.c
字号:
#ifndef lintstatic const char sccsid[] = "@(#)escape.c 1.1 96/11/02 Edward Falk" ;#endif/********** * * * @@@@@ @@@@ @@@ @@@ @@@@ @@@@@ * @ @ @ @ @ @ @ @ * @@@ @@@ @ @@@@@ @@@@ @@@ * @ @ @ @ @ @ @ * @@@@@ @@@@ @@@ @ @ @ @@@@@ * * ESCAPE - filename completion * * int * filenam_escape(name,maxlen) filename completion. * char *name ; pathname * int maxlen ; maximum length of pathname * * This routine takes a pathname and completes it as far as possible. * escape returns the number of matches, or -1 on error. If the number * of matches is not exactly 1, we probably don't have a complete path * and the application should ring the bell. * * This function also completes user names in "~user" form. This can * be very slow if there are a lot of password entries. * * Note: escape optimizes the case where no expansion at all can be * performed. When this happens, the returned number of matches will * be short (but greater than 1) * * * int * filename_expand(name) '~' expansion. * char *name ; * * This function expands a filename with a leading '~', in place. * 'name' must point to a buffer long enough to hold the complete * path. If the form is "~user" and the password entry for the * user cannot be found, an error occurs. This function returns 0 * on success, nonzero on failure. * * * * * Edward A. Falk * Sun Microsystems * * September, 1990 * * * **********/#include <stdio.h>#include <sys/types.h>#include <string.h>#include <dirent.h>#include <sys/stat.h>#include <sys/param.h> /* defines MAXPATHLEN */#include <pwd.h>extern char *getenv() ;/* return values from parse() function */static int unamecomp ; /* username completion? */static DIR *dir ; /* directory to search, if any */static char *namestr ; /* part of name where results will go */static int matchlen ; /* length of namestr *//* cute optimization */#define STRCMP(a,b) ( *(a)!=*(b) || strcmp((a),(b)) )#define STRNCMP(a,b,l) ( *(a)!=*(b) || strncmp((a),(b),(l)) )#ifdef STANDALONEmain(){ test("a") ; test("f") ; test("e") ; test("et") ; test("n") ; test("~/Es") ; test("~/Escape/f") ; test("~/Escape/et") ; test("/vm") ; test("~falk/") ; test("~moose/") ; test("~fal") ; test("~jput") ; test("~jp") ; test("~") ; test2("~falk/los") ; test2("~falk") ; test2("~moose/") ; exit(0) ;}test(str) char *str ;{ char path[MAXPATHLEN] ; int i ; strcpy(path, str) ; i = escape(path, MAXPATHLEN) ; printf("# matches = %d, path=%s\n", i, path) ;}test2(str) char *str ;{ char path[MAXPATHLEN] ; int i ; strcpy(path, str) ; i = expand_user(path) ; printf("path=%s\n", path) ;}#endif /* STANDALONE */static intparse(name,maxlen) char *name ; /* file to match */ int maxlen ;{ char dirname[MAXPATHLEN] ; char *homedir ; char *dirstr ; struct passwd *passent ; /* cases: * "~" username matching * "~/ get home directory * "~xx username matching * "~xx/ get username * "/ root * anything "." */ unamecomp = 0 ; dir = NULL ; if( name[0] == '~' ) { if( name[1] == '/' ) { homedir = getenv("HOME") ; if( homedir == NULL ) return -1 ; strcpy(dirname, homedir) ; strcat(dirname, name+1) ; namestr = strrchr(name, '/') + 1 ; *strrchr(dirname, '/') = '\0' ; dir = opendir(dirname) ; } else { dirstr = strchr(name, '/') ; if( dirstr == NULL ) /* username matching */ { unamecomp = 1 ; namestr = name+1 ; matchlen = strlen(namestr) ; return 0 ; } else { *dirstr = '\0' ; passent = getpwnam(name+1) ; *dirstr = '/' ; if( passent == NULL ) return -1 ; strcpy(dirname, passent->pw_dir) ; strcat(dirname, dirstr) ; namestr = strrchr(name,'/') + 1 ; *strrchr(dirname, '/') = '\0' ; dir = opendir(dirname) ; } } } else { strcpy(dirname, name) ; namestr = strrchr(name, '/') ; if( namestr == NULL ) /* no path */ { namestr = name ; dir = opendir(".") ; } else if( namestr == name ) /* absolute path */ { ++namestr ; dir = opendir("/") ; } else /* relative path */ { ++namestr ; *strrchr(dirname, '/') = '\0' ; dir = opendir(dirname) ; } } matchlen = strlen(namestr) ; return dir == NULL ;}intfilename_escape(name,maxlen) char *name ; /* file to match */ int maxlen ;{ int nummatch = 0 ; struct dirent *entry ; struct passwd *passent ; int copout = 0 ; /* unable to expand at all */ if( parse(name,maxlen) ) return 0 ; if( matchlen == 0 ) return 2 ; if( !unamecomp ) { /* now to search the directory for matches */ while( !copout && (entry = readdir(dir)) != NULL ) { if( STRCMP(entry->d_name, ".") != 0 && STRCMP(entry->d_name, "..") != 0 && STRNCMP(namestr, entry->d_name, matchlen) == 0 ) { if( ++nummatch == 1 ) /* first match */ strcpy(namestr, entry->d_name) ; else /* ambiguity! */ { char *ptr1=namestr+matchlen, *ptr2=entry->d_name+matchlen ; while( *ptr1 == *ptr2 ) ++ptr1, ++ptr2 ; *ptr1 = '\0' ; copout = ptr1 == namestr+matchlen ; } } } closedir(dir) ; } else { setpwent() ; while( !copout && (passent = getpwent()) != NULL ) { if( STRNCMP(namestr, passent->pw_name, matchlen) == 0 ) { if( nummatch == 0 ) /* first match */ { strcpy(namestr, passent->pw_name) ; nummatch = 1 ; } else /* ambiguity! */ { char *ptr1=namestr+matchlen, *ptr2=passent->pw_name+matchlen ; while( *ptr1 != '\0' && *ptr1 == *ptr2 ) ++ptr1, ++ptr2 ; if( *ptr1 != *ptr2 ) { *ptr1 = '\0' ; ++nummatch ; copout = ptr1 == namestr+matchlen ; } } } } } return nummatch ;}intfilename_expand(name) char *name ; /* file to match */{ char dirname[MAXPATHLEN] ; char *homedir ; char *dirstr ; struct passwd *passent ; if( name[0] != '~' ) return 0 ; /* that was easy */ /* cases: * "~" fail * "~/ get home directory * "~xx username matching */ if( name[1] == '/' ) { homedir = getenv("HOME") ; if( homedir == NULL ) return -1 ; strcpy(dirname, homedir) ; strcat(dirname, name+1) ; strcpy(name,dirname) ; } else { dirstr = strchr(name, '/') ; if( dirstr != NULL ) *dirstr = '\0' ; passent = getpwnam(name+1) ; if( dirstr != NULL ) *dirstr = '/' ; if( passent == NULL ) return -1 ; strcpy(dirname, passent->pw_dir) ; if( dirstr != NULL ) strcat(dirname, dirstr) ; strcpy(name,dirname) ; } return 0 ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -