]> git.lizzy.rs Git - bspwm.git/blob - src/helpers.c
Escape shell characters in the erc arguments
[bspwm.git] / src / helpers.c
1 /* Copyright (c) 2012, Bastien Dejean
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this
8  *    list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <stdarg.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <ctype.h>
34 #include "bspwm.h"
35
36 void warn(char *fmt, ...)
37 {
38         va_list ap;
39         va_start(ap, fmt);
40         vfprintf(stderr, fmt, ap);
41         va_end(ap);
42 }
43
44 __attribute__((noreturn))
45 void err(char *fmt, ...)
46 {
47         va_list ap;
48         va_start(ap, fmt);
49         vfprintf(stderr, fmt, ap);
50         va_end(ap);
51         exit(EXIT_FAILURE);
52 }
53
54 char *read_string(const char *file_path, size_t *tlen)
55 {
56         if (file_path == NULL) {
57                 return NULL;
58         }
59
60         int fd = open(file_path, O_RDONLY);
61
62         if (fd == -1) {
63                 perror("Read file: open");
64                 return NULL;
65         }
66
67         char buf[BUFSIZ], *content = NULL;
68         size_t len = sizeof(buf);
69
70         if ((content = calloc(len, sizeof(char))) == NULL) {
71                 perror("Read file: calloc");
72                 goto end;
73         }
74
75         int nb;
76         *tlen = 0;
77
78         while (true) {
79                 nb = read(fd, buf, sizeof(buf));
80                 if (nb < 0) {
81                         perror("Restore tree: read");
82                         free(content);
83                         content = NULL;
84                         goto end;
85                 } else if (nb == 0) {
86                         break;
87                 } else {
88                         *tlen += nb;
89                         if (*tlen > len) {
90                                 len *= 2;
91                                 char *rcontent = realloc(content, len * sizeof(char));
92                                 if (rcontent == NULL) {
93                                         perror("Read file: realloc");
94                                         free(content);
95                                         content = NULL;
96                                         goto end;
97                                 } else {
98                                         content = rcontent;
99                                 }
100                         }
101                         strncpy(content + (*tlen - nb), buf, nb);
102                 }
103         }
104
105 end:
106         close(fd);
107         return content;
108 }
109
110 char *copy_string(char *str, size_t len)
111 {
112         char *cpy = calloc(1, ((len+1) * sizeof(char)));
113         if (cpy == NULL) {
114                 perror("Copy string: calloc");
115                 return NULL;
116         }
117         strncpy(cpy, str, len);
118         cpy[len] = '\0';
119         return cpy;
120 }
121
122 char *shell_escape(char *s)
123 {
124         char *e = malloc(2 * strlen(s) + 1);
125
126         if (e == NULL) {
127                 return NULL;
128         }
129
130         int c = 0;
131         int j = 0;
132
133         for (size_t i = 0; i < strlen(s); i++) {
134                 if (s[i] == '\\') {
135                         c += 1;
136                 } else {
137                         if (s[i] == '$' || s[i] == '(' || s[i] == ')') {
138                                 if (c % 2 == 0) {
139                                         e[j++] = '\\';
140                                 }
141                         }
142                         c = 0;
143                 }
144                 e[j++] = s[i];
145         }
146
147         e[j] = '\0';
148         return e;
149 }
150
151 char *mktempfifo(const char *template)
152 {
153         int tempfd;
154         char *runtime_dir = getenv(RUNTIME_DIR_ENV);
155         if (runtime_dir == NULL) {
156                 runtime_dir = "/tmp";
157         }
158
159         char *fifo_path = malloc(strlen(runtime_dir)+1+strlen(template)+1);
160         if (fifo_path == NULL) {
161                 return NULL;
162         }
163
164         sprintf(fifo_path, "%s/%s", runtime_dir, template);
165
166         if ((tempfd = mkstemp(fifo_path)) == -1) {
167                 free(fifo_path);
168                 return NULL;
169         }
170
171         close(tempfd);
172         unlink(fifo_path);
173
174         if (mkfifo(fifo_path, 0666) == -1) {
175                 free(fifo_path);
176                 return NULL;
177         }
178
179         return fifo_path;
180 }
181
182 int asprintf(char **buf, const char *fmt, ...)
183 {
184         int size = 0;
185         va_list args;
186         va_start(args, fmt);
187         size = vasprintf(buf, fmt, args);
188         va_end(args);
189         return size;
190 }
191
192 int vasprintf(char **buf, const char *fmt, va_list args)
193 {
194         va_list tmp;
195         va_copy(tmp, args);
196         int size = vsnprintf(NULL, 0, fmt, tmp);
197         va_end(tmp);
198
199         if (size < 0) {
200                 return -1;
201         }
202
203         *buf = malloc(size + 1);
204
205         if (*buf == NULL) {
206                 return -1;
207         }
208
209         size = vsprintf(*buf, fmt, args);
210         return size;
211 }
212
213 bool is_hex_color(const char *color)
214 {
215         if (color[0] != '#' || strlen(color) != 7) {
216                 return false;
217         }
218         for (int i = 1; i < 7; i++) {
219                 if (!isxdigit(color[i])) {
220                         return false;
221                 }
222         }
223         return true;
224 }