1 /*
2 * vim:ts=4:sw=4:expandtab
3 *
4 * Copyright © 2016 Ingo Bürk
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Except as contained in this notice, the names of the authors or their
24 * institutions shall not be used in advertising or otherwise to promote the
25 * sale, use or other dealings in this Software without prior written
26 * authorization from the authors.
27 *
28 */
29 #include "externals.h"
30
31 #include "util.h"
32
str2long(long * out,const char * input,const int base)33 int str2long(long *out, const char *input, const int base) {
34 char *end;
35 long result;
36
37 if (input[0] == '\0' || isspace(input[0]))
38 return -FAILURE;
39
40 errno = 0;
41 result = strtol(input, &end, base);
42 if (errno == ERANGE && result == LONG_MAX)
43 return -FAILURE;
44 if (errno == ERANGE && result == LONG_MIN)
45 return -FAILURE;
46 if (*end != '\0')
47 return -FAILURE;
48
49 *out = result;
50 return SUCCESS;
51 }
52
get_home_dir_file(const char * filename)53 char *get_home_dir_file(const char *filename) {
54 char *result;
55
56 char *home = getenv("HOME");
57 if (home == NULL)
58 return NULL;
59
60 if (asprintf(&result, "%s/%s", home, filename) < 0)
61 return NULL;
62
63 return result;
64 }
65
resolve_path(const char * path,const char * _base)66 char *resolve_path(const char *path, const char *_base) {
67 char *base;
68 char *result;
69
70 if (path[0] == '/')
71 return strdup(path);
72
73 base = (_base == NULL) ? getcwd(NULL, 0) : strdup(_base);
74 if (base == NULL)
75 return NULL;
76
77 if (asprintf(&result, "%s/%s", base, path) < 0) {
78 FREE(base);
79 return NULL;
80 }
81 FREE(base);
82
83 return result;
84 }
85
file_get_contents(const char * filename)86 char *file_get_contents(const char *filename) {
87 FILE *file;
88 struct stat stbuf;
89 size_t file_size;
90 char *content;
91
92 if ((file = fopen(filename, "rb")) == NULL)
93 return NULL;
94
95 /* We want to read the file in one go, so figure out the file size. */
96 if (fstat(fileno(file), &stbuf) < 0) {
97 fclose(file);
98 return NULL;
99 }
100 file_size = stbuf.st_size;
101
102 /* Read the file content. */
103 content = calloc(file_size + 1, 1);
104 if (content == NULL) {
105 fclose(file);
106 return NULL;
107 }
108
109 if (fread(content, 1, file_size, file) != file_size) {
110 FREE(content);
111 fclose(file);
112 return NULL;
113 }
114
115 fclose(file);
116 content[file_size] = '\0';
117 return content;
118 }
119
xcb_util_get_property(xcb_connection_t * conn,xcb_window_t window,xcb_atom_t atom,xcb_atom_t type,size_t size)120 char *xcb_util_get_property(xcb_connection_t *conn, xcb_window_t window, xcb_atom_t atom,
121 xcb_atom_t type, size_t size) {
122 xcb_get_property_cookie_t cookie;
123 xcb_get_property_reply_t *reply;
124 xcb_generic_error_t *err;
125 int reply_length;
126 char *content;
127
128 cookie = xcb_get_property(conn, 0, window, atom, type, 0, size);
129 reply = xcb_get_property_reply(conn, cookie, &err);
130 if (err != NULL) {
131 FREE(err);
132 return NULL;
133 }
134
135 if (reply == NULL || (reply_length = xcb_get_property_value_length(reply)) == 0) {
136 FREE(reply);
137 return NULL;
138 }
139
140 if (reply->bytes_after > 0) {
141 size_t adjusted_size = size + ceil(reply->bytes_after / 4.0);
142 FREE(reply);
143 return xcb_util_get_property(conn, window, atom, type, adjusted_size);
144 }
145
146 if (asprintf(&content, "%.*s", reply_length, (char *)xcb_get_property_value(reply)) < 0) {
147 FREE(reply);
148 return NULL;
149 }
150
151 FREE(reply);
152 return content;
153 }
154