diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2007-09-25 15:55:26 -0700 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2007-09-25 15:55:26 -0700 |
commit | e9a79a249cec69fc178098d2f75db9389068510a (patch) | |
tree | 0e366094b7fecd3988c243fbbb574015e0c900c8 /src/cli_path_utils.c | |
download | vyatta-cfg-e9a79a249cec69fc178098d2f75db9389068510a.tar.gz vyatta-cfg-e9a79a249cec69fc178098d2f75db9389068510a.zip |
initial import (from eureka /cli) plus new build system.upstream
Diffstat (limited to 'src/cli_path_utils.c')
-rw-r--r-- | src/cli_path_utils.c | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/src/cli_path_utils.c b/src/cli_path_utils.c new file mode 100644 index 0000000..4045516 --- /dev/null +++ b/src/cli_path_utils.c @@ -0,0 +1,535 @@ + +/************************************************************************ + + Module: cli + + **** License **** + Version: VPL 1.0 + + The contents of this file are subject to the Vyatta Public License + Version 1.0 ("License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.vyatta.com/vpl + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + This code was originally developed by Vyatta, Inc. + Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc. + All Rights Reserved. + + Author: Oleg Moskalenko + Date: 2007 + Description: "new" cli path-handling utilities + + **** End License **** + +*************************************************************************/ + +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/wait.h> +#include <unistd.h> +#include <dirent.h> +#include <limits.h> +#include <stdarg.h> +#include <regex.h> +#include <dirent.h> + +#include <string.h> + +#include "cli_path_utils.h" + +/********************* + * Data definitions + * + *********************/ + +typedef char* clind_dir_name; + +/** + * Definition of the path structure to hold all path-like information: + */ + +struct _clind_path_impl { + + int absolute; + int path_len; + char* path_string; + clind_dir_name* path; + +}; + +/****************************** + * Path utils. We use them + * to manipulate the path-like + * structures. + * + ******************************/ + +static void clind_reset_path_string(clind_path_impl* obj) { + + char* newpath=NULL; + + if(obj->path_len<1) { + + newpath=strdup(""); + + } else { + + int i=0; + + if(!obj->absolute || (strlen(obj->path[0])>0 && ((char*)(obj->path[0]))[0]=='/')) { + newpath=strdup(obj->path[0]); + } else { + newpath=(char*)malloc(strlen(obj->path[0])+1+1); + newpath[0]='/'; + strcpy(newpath+1,(char*)(obj->path[0])); + } + + for(i=1;i<obj->path_len;i++) { + newpath=(char*)realloc(newpath,strlen(newpath)+1+strlen(obj->path[i])+1); + strcpy(newpath+strlen(newpath),"/"); + strcpy(newpath+strlen(newpath),obj->path[i]); + } + } + + if(obj->path_string==NULL) { + obj->path_string=newpath; + } else { + obj->path_string=(char*)realloc(obj->path_string,strlen(newpath)+1); + strcpy(obj->path_string,newpath); + free(newpath); + } +} + +clind_path_ref clind_path_construct(const char* path) { + + if(!path) return NULL; + else { + + const char* delim="/ \t"; + + clind_path_impl *obj = (clind_path_impl*)malloc(sizeof(clind_path_impl)); + char* tokpath=strdup(path); + char* token=strtok(tokpath,delim); + + obj->path_len=0; + obj->path_string=strdup(""); + obj->path=NULL; + + while(token) { + clind_path_push((clind_path_ref)obj,token); + token=strtok(NULL,delim); + } + + free(tokpath); + + obj->absolute=(*path=='/'); + + clind_reset_path_string(obj); + + return (clind_path_ref)obj; + } +} + +void clind_path_destruct(clind_path_ref* path) { + + if(path && *path) { + + clind_path_impl* obj = (clind_path_impl*)(*path); + + if(obj->path_string) { + free(obj->path_string); + obj->path_string=NULL; + } + + if(obj->path) { + while(obj->path_len>0) { + char* dir_name = (char*)(obj->path[obj->path_len-1]); + if(dir_name) { + free(dir_name); + } + obj->path_len--; + } + free(obj->path); + obj->path=0; + } + + *path=0; + } +} + +clind_path_ref clind_path_clone(const clind_path_ref path) { + + clind_path_ref ret=NULL; + if(path) { + + clind_path_impl* obj = (clind_path_impl*)path; + + ret = clind_path_construct(obj->path_string); + + if(ret) { + + ((clind_path_impl*)ret)->absolute=obj->absolute; + + clind_reset_path_string((clind_path_impl*)ret); + } + } + + return ret; +} + +int clind_path_get_size(clind_path_ref path) { + if(path) { + clind_path_impl* obj = (clind_path_impl*)path; + return obj->path_len; + } + return 0; +} + +const char* clind_path_get_path_string(clind_path_ref path) { + if(path) { + clind_path_impl* obj = (clind_path_impl*)path; + if(obj->path_string) { + return obj->path_string; + } + } + return ""; +} + +int clind_path_is_absolute(clind_path_ref path) { + if(path) { + clind_path_impl* obj = (clind_path_impl*)path; + return obj->absolute; + } + return 0; +} + +void clind_path_push(clind_path_ref path,const char* dir) { + + if(path && dir && *dir) { + + clind_path_impl* obj = (clind_path_impl*)path; + int absolute=(*dir=='/'); + + while(*dir && *dir=='/') dir++; + + if(obj->path_len<=0) { + + obj->path_len=1; + obj->absolute=absolute; + + if(obj->path) { + free(obj->path); + } + + obj->path=(clind_dir_name*)malloc(sizeof(clind_dir_name)); + obj->path[0]=(clind_dir_name)strdup(dir); + + } else { + + obj->path_len++; + + obj->path=(clind_dir_name*)realloc(obj->path, + sizeof(clind_dir_name)*(obj->path_len)); + obj->path[obj->path_len-1]=strdup(dir); + } + + clind_reset_path_string(obj); + } +} + +char* clind_path_pop_string(clind_path_ref path) { + + char* ret=NULL; + + if(path) { + + clind_path_impl* obj = (clind_path_impl*)path; + + if(obj->path_len<=0) { + return ret; + } + + obj->path_len--; + + if(obj->path) { + if(obj->path[obj->path_len]) { + ret = obj->path[obj->path_len]; + obj->path[obj->path_len]=NULL; + } + } + + if(obj->path_len<1) { + obj->absolute=0; + } + + clind_reset_path_string(obj); + } + + return ret; +} + +int clind_path_pop(clind_path_ref path) { + + int ret=-1; + + char* ps = clind_path_pop_string(path); + + if(ps) { + free(ps); + ret=0; + } + + return ret; +} + +const char* clind_path_last_string(clind_path_ref path) { + + char* ret=NULL; + + if(path) { + clind_path_impl* obj = (clind_path_impl*)path; + if(obj->path && obj->path_len>0) { + ret=obj->path[obj->path_len-1]; + } + } + + return ret; +} + +void clind_path_unshift(clind_path_ref path,const char* dir) { + + if(path && dir && *dir) { + + clind_path_impl* obj = (clind_path_impl*)path; + + int absolute=(*dir=='/'); + + while(*dir && *dir=='/') dir++; + + if(obj->path_len<=0) { + + clind_path_push(path,dir); + + } else { + + obj->path_len++; + + obj->path=(clind_dir_name*)realloc(obj->path, + sizeof(clind_dir_name)*(obj->path_len)); + memmove((char*)(obj->path)+sizeof(clind_dir_name),(char*)(obj->path), + sizeof(clind_dir_name)*(obj->path_len-1)); + obj->path[0]=strdup(dir); + + } + + obj->absolute=absolute; + + clind_reset_path_string(obj); + } +} + +const char* clind_path_get_string(clind_path_ref path,int index) { + + const char* ret=NULL; + + if(path) { + clind_path_impl* obj = (clind_path_impl*)path; + if(obj->path && obj->path_len>index) { + ret=obj->path[index]; + } + } + + return ret; +} + +const char* clind_path_first_string(clind_path_ref path) { + return clind_path_get_string(path,0); +} + +char* clind_path_shift_string(clind_path_ref path) { + + char* ret=NULL; + + if(path) { + + clind_path_impl* obj = (clind_path_impl*)path; + + if(obj->path_len<=0) { + return ret; + } + + obj->path_len--; + + if(obj->path) { + if(obj->path[0]) { + ret = obj->path[0]; + obj->path[0]=NULL; + } + + memmove((char*)(obj->path),(char*)(obj->path)+sizeof(clind_dir_name), + sizeof(clind_dir_name)*obj->path_len); + } + + obj->absolute=0; + + clind_reset_path_string(obj); + } + + return ret; +} + +int clind_path_shift(clind_path_ref path) { + + int ret=-1; + + char* ps = clind_path_shift_string(path); + + if(ps) { + free(ps); + ret=0; + } + + return ret; +} + +void clind_path_debug_print(clind_path_ref path) { + + if(path) { + + int i=0; + clind_path_impl* obj = (clind_path_impl*)path; + + if(obj->path_string) { + printf("obj->path_string=%s, obj->path_len=%d,obj->absolute=%d\n", + obj->path_string,obj->path_len,obj->absolute); + } else { + printf("obj->path_string=NULL, obj->path_len=%d,obj->absolute=%d\n", + obj->path_len,obj->absolute); + } + + if(obj->path) { + for(i=0;i<obj->path_len;i++) { + if(obj->path[i]) { + printf(" obj->path[%d]=%s\n",i,obj->path[i]); + } else { + printf(" obj->path[%d]=NULL\n",i); + } + } + } else { + printf(" obj->path=NULL\n"); + } + } +} + +int clind_file_exists(const char* dir,const char* file) { + + int ret=0; + + if(file) { + + char* fname=strdup(file); + struct stat statbuf; + + if(dir) { + free(fname); + fname=(char*)malloc(strlen(dir)+1+strlen(file)+1); + strcpy(fname,dir); + strcpy(fname+strlen(fname),"/"); + strcpy(fname+strlen(fname),file); + } + + if (lstat(fname, &statbuf) == 0) { + ret=1; + } + + free(fname); + } + + return ret; +} + +char *clind_unescape(const char *name) +{ + const char *cp; + char *rcp, *ret; + char len; + + for(cp=name, len=0;*cp;++cp, ++len) + if(*cp=='%') + cp +=2; + rcp = ret = malloc(len+1); + for(cp=name, len=0;*cp;++cp, ++rcp) + if(*cp=='%') { + ++cp; + if (*cp >='a' && *cp<='f') + *rcp = (*cp-'a'+10)*16; + else if (*cp >='A' && *cp<='F') + *rcp = (*cp-'A'+10)*16; + else if (*cp >='0' && *cp<='9') + *rcp = (*cp-'0')*16; + else { + printf("Bad escape in |%s|\n", name); + exit(-1); + } + ++cp; + if (*cp >='a' && *cp<='f') + *rcp += (*cp-'a'+10); + else if (*cp >='A' && *cp<='F') + *rcp += (*cp-'A'+10); + else if (*cp >='0' && *cp<='9') + *rcp += (*cp-'0'); + else { + printf("Bad escape in |%s|\n", name); + exit(-1); + } + }else + *rcp = *cp; + *rcp = 0; + return ret; +} + +char* clind_quote(const char* s) { + + char* ret=NULL; + if(s) { + int i=0; + int len=strlen(s); + int sz=0; + char SQ='\''; + + ret=(char*)malloc(1+5*len+1+1+10); + ret[sz++]=SQ; + + for(i=0;i<len;i++) { + if(s[i]==SQ) { + ret[sz++]=SQ;/*'\''*/ + ret[sz++]='\\'; + ret[sz++]=SQ; + ret[sz++]=SQ; + } else { + ret[sz++]=s[i]; + } + } + + ret[sz++]=SQ; + ret[sz]=0; + } + return ret; +} + + |