1 #include "common.h"
2 
3 /* expand a path relative to some `.' */
4 extern String *
abspath(char * path,char * dot,String * to)5 abspath(char *path, char *dot, String *to)
6 {
7 	if (*path == '/') {
8 		to = s_append(to, path);
9 	} else {
10 		to = s_append(to, dot);
11 		to = s_append(to, "/");
12 		to = s_append(to, path);
13 	}
14 	return to;
15 }
16 
17 /* return a pointer to the base component of a pathname */
18 extern char *
basename(char * path)19 basename(char *path)
20 {
21 	char *cp;
22 
23 	cp = strrchr(path, '/');
24 	return cp==0 ? path : cp+1;
25 }
26 
27 /* append a sub-expression match onto a String */
28 extern void
append_match(Resub * subexp,String * sp,int se)29 append_match(Resub *subexp, String *sp, int se)
30 {
31 	char *cp, *ep;
32 
33 	cp = subexp[se].s.sp;
34 	ep = subexp[se].e.ep;
35 	for (; cp < ep; cp++)
36 		s_putc(sp, *cp);
37 	s_terminate(sp);
38 }
39 
40 /*
41  *  check for shell characters in a String
42  */
43 static char *illegalchars = "\r\n";
44 
45 extern int
shellchars(char * cp)46 shellchars(char *cp)
47 {
48 	char *sp;
49 
50 	for(sp=illegalchars; *sp; sp++)
51 		if(strchr(cp, *sp))
52 			return 1;
53 	return 0;
54 }
55 
56 static char *specialchars = " ()<>{};=\\'`^&|";
57 static char *escape = "%%";
58 
59 int
hexchar(int x)60 hexchar(int x)
61 {
62 	x &= 0xf;
63 	if(x < 10)
64 		return '0' + x;
65 	else
66 		return 'A' + x - 10;
67 }
68 
69 /*
70  *  rewrite a string to escape shell characters
71  */
72 extern String*
escapespecial(String * s)73 escapespecial(String *s)
74 {
75 	String *ns;
76 	char *sp;
77 
78 	for(sp = specialchars; *sp; sp++)
79 		if(strchr(s_to_c(s), *sp))
80 			break;
81 	if(*sp == 0)
82 		return s;
83 
84 	ns = s_new();
85 	for(sp = s_to_c(s); *sp; sp++){
86 		if(strchr(specialchars, *sp)){
87 			s_append(ns, escape);
88 			s_putc(ns, hexchar(*sp>>4));
89 			s_putc(ns, hexchar(*sp));
90 		} else
91 			s_putc(ns, *sp);
92 	}
93 	s_terminate(ns);
94 	s_free(s);
95 	return ns;
96 }
97 
98 uint
hex2uint(char x)99 hex2uint(char x)
100 {
101 	if(x >= '0' && x <= '9')
102 		return x - '0';
103 	if(x >= 'A' && x <= 'F')
104 		return (x - 'A') + 10;
105 	if(x >= 'a' && x <= 'f')
106 		return (x - 'a') + 10;
107 	return -512;
108 }
109 
110 /*
111  *  rewrite a string to remove shell characters escapes
112  */
113 extern String*
unescapespecial(String * s)114 unescapespecial(String *s)
115 {
116 	String *ns;
117 	char *sp;
118 	uint c, n;
119 
120 	if(strstr(s_to_c(s), escape) == 0)
121 		return s;
122 	n = strlen(escape);
123 
124 	ns = s_new();
125 	for(sp = s_to_c(s); *sp; sp++){
126 		if(strncmp(sp, escape, n) == 0){
127 			c = (hex2uint(sp[n])<<4) + hex2uint(sp[n+1]);
128 			if(c < 0)
129 				s_putc(ns, *sp);
130 			else {
131 				s_putc(ns, c);
132 				sp += n+2-1;
133 			}
134 		} else
135 			s_putc(ns, *sp);
136 	}
137 	s_terminate(ns);
138 	s_free(s);
139 	return ns;
140 
141 }
142 
143 int
returnable(char * path)144 returnable(char *path)
145 {
146 
147 	return strcmp(path, "/dev/null") != 0;
148 }
149