4 #if !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
5 #define _XOPEN_SOURCE 700
7 #define _FILE_OFFSET_BITS 64
11 #include <glib/gi18n-lib.h>
19 #include <sys/types.h>
38 const size_t len = strlen(path);
42 if (len > 1 && path[1] !=
'/') {
43 while (path[idx] && path[idx] !=
'/') {
47 user = g_strndup(path + 1, idx - 1);
53 if (home_path == NULL) {
54 return g_strdup(path);
57 rpath = g_build_filename(home_path, path + idx, NULL);
60 rpath = g_strdup(path);
69 if (uri == NULL || strlen(uri) == 0) {
73 GString* command = g_string_new(
"xdg-open ");
74 char* tmp = g_shell_quote(uri);
76 g_string_append(command, tmp);
80 bool res = g_spawn_command_line_async(command->str, &error);
86 g_string_free(command, TRUE);
93 if (user == NULL || g_strcmp0(user, g_get_user_name()) == 0) {
94 #if GLIB_CHECK_VERSION(2, 35, 3)
95 return g_strdup(g_get_home_dir());
97 const char* homedir = g_getenv(
"HOME");
98 return g_strdup(homedir ? homedir : g_get_home_dir());
104 struct passwd* result = NULL;
105 #ifdef _SC_GETPW_R_SIZE_MAX
106 int bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
114 char* buffer = g_try_malloc0(
sizeof(
char) * bufsize);
115 if (buffer == NULL) {
119 getpwnam_r(user, &pwd, buffer, bufsize, &result);
120 if (result == NULL) {
125 char* dir = g_strdup(pwd.pw_dir);
133 static const char* VARS[] = {
140 static const char* DEFAULTS[] = {
144 "/usr/local/share/:/usr/share",
149 return g_strdup(g_get_user_data_dir());
151 return g_strdup(g_get_user_config_dir());
155 const char* tmp = g_getenv(VARS[path]);
156 if (tmp == NULL || !g_strcmp0(tmp,
"")) {
157 return g_strdup(DEFAULTS[path]);
159 return g_strdup(tmp);
169 if (patharray == NULL || !g_strcmp0(patharray,
"")) {
174 char** paths = g_strsplit(patharray,
":", 0);
175 for (
size_t i = 0; paths[i] != NULL; ++i) {
188 if (fixed_path == NULL || mode == NULL) {
192 FILE* fp = fopen(fixed_path, mode);
243 #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
252 char* line = fgetln(file, &size);
257 char* copy = strndup(line, size);
263 g_strdelimit(copy,
"\n\r",
'\0');
277 if (getline(&line, &size, file) == -1) {
285 g_strdelimit(line,
"\n\r",
'\0');
314 const off_t curpos = ftello(file);
319 fseeko(file, 0, SEEK_END);
320 const off_t size = ftello(file) - curpos;
321 fseeko(file, curpos, SEEK_SET);
324 char* content = malloc(1);
329 if ((uintmax_t)size >= (uintmax_t)SIZE_MAX) {
334 char* buffer = malloc(size + 1);
335 if (buffer == NULL) {
339 size_t read = fread(buffer, size, 1, file);
360 for(i = 0; i < strlen(line); i++) {
361 if (isspace(line[i]) != 0) {
362 if (ws_mode ==
true) {
388 void* tmp = realloc(*ptr, size);
411 if ((keyval >=
'!' && keyval <=
'/')
412 || (keyval >=
':' && keyval <=
'@')
413 || (keyval >=
'[' && keyval <=
'`')
414 || (keyval >=
'{' && keyval <=
'~')
416 *state |= GDK_SHIFT_MASK;
427 GString* str = g_string_new(
"");
428 while (*value !=
'\0') {
429 const char c = *value++;
430 if (strchr(
"\\ \t\"\'", c) != NULL) {
431 g_string_append_c(str,
'\\');
433 g_string_append_c(str, c);
436 return g_string_free(str, FALSE);
442 if (
string == NULL || old == NULL ||
new == NULL) {
446 size_t old_len = strlen(old);
447 size_t new_len = strlen(
new);
453 for (i = 0;
string[i] !=
'\0'; i++) {
454 if (strstr(&
string[i], old) == &
string[i]) {
461 return g_strdup(
string);
464 char* ret = g_try_malloc0(
sizeof(
char) * (i - count * old_len + count * new_len + 1));
471 while (*
string !=
'\0') {
472 if (strstr(
string, old) ==
string) {
473 strncpy(iter,
new, new_len);
487 if (session == NULL || argument_list == NULL) {
493 if (cmd == NULL || strlen(cmd) == 0) {
494 girara_debug(
"exec-command is empty, executing directly.");
499 bool dont_append_first_space = cmd == NULL;
500 GString* command = g_string_new(cmd ? cmd :
"");
504 if (dont_append_first_space ==
false) {
505 g_string_append_c(command,
' ');
507 dont_append_first_space =
false;
508 char* tmp = g_shell_quote(value);
509 g_string_append(command, tmp);
513 GError* error = NULL;
515 gboolean ret = g_spawn_command_line_async(command->str, &error);
522 g_string_free(command, TRUE);
530 if (widget == NULL || styleclass == NULL) {
534 GtkStyleContext* context = gtk_widget_get_style_context(widget);
535 gtk_style_context_add_class(context, styleclass);
char * girara_replace_substring(const char *string, const char *old, const char *new)
#define girara_debug(...)
void girara_list_append(girara_list_t *list, void *data)
FILE * girara_file_open(const char *path, const char *mode)
girara_list_t * girara_split_path_array(const char *patharray)
girara_list_t * girara_list_new2(girara_free_function_t gfree)
bool girara_xdg_open(const char *uri)
void update_state_by_keyval(int *state, int keyval)
void girara_clean_line(char *line)
char * girara_file_read(const char *path)
char * girara_file_read_line(FILE *file)
char * girara_fix_path(const char *path)
bool girara_setting_get(girara_session_t *session, const char *name, void *dest)
#define girara_error(...)
#define girara_warning(...)
char * girara_file_read2(FILE *file)
void * girara_safe_realloc(void **ptr, size_t size)
void girara_notify(girara_session_t *session, int level, const char *format,...)
char * girara_get_xdg_path(girara_xdg_path_t path)
bool girara_exec_with_argument_list(girara_session_t *session, girara_list_t *argument_list)
char * girara_escape_string(const char *value)
void widget_add_class(GtkWidget *widget, const char *styleclass)
#define GIRARA_LIST_FOREACH_END(list, type, iter, data)
#define GIRARA_LIST_FOREACH(list, type, iter, data)
char * girara_get_home_directory(const char *user)