summaryrefslogtreecommitdiff
path: root/src/cli_path_utils.c
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2007-09-25 15:55:26 -0700
committerAn-Cheng Huang <ancheng@vyatta.com>2007-09-25 15:55:26 -0700
commite9a79a249cec69fc178098d2f75db9389068510a (patch)
tree0e366094b7fecd3988c243fbbb574015e0c900c8 /src/cli_path_utils.c
downloadvyatta-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.c535
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;
+}
+
+