Fixed wrong keybinding for cancel load in manpage.
[vimprobable2.git] / utilities.c
blobeb62c9356fe79d689ee6ddb37be8a966cd964b3a
1 /*
2 (c) 2009 by Leon Winter
3 (c) 2009-2012 by Hannes Schueller
4 (c) 2009-2010 by Matto Fransen
5 (c) 2010-2011 by Hans-Peter Deifel
6 (c) 2010-2011 by Thomas Adam
7 see LICENSE file
8 */
10 #include "includes.h"
11 #include "vimprobable.h"
12 #include "main.h"
13 #include "utilities.h"
15 extern GList *commandhistory;
16 extern int commandpointer;
17 extern Command commands[COMMANDSIZE];
18 extern KeyList *keylistroot;
19 extern Key keys[];
20 extern char *error_msg;
21 extern gboolean complete_case_sensitive;
22 extern char *config_base;
23 static GList *dynamic_searchengines = NULL, *dynamic_uri_handlers = NULL;
25 void add_modkeys(char key);
27 void save_command_history(char *line)
29 char *c = line;
31 while (isspace(*c) && *c)
32 c++;
33 if (!strlen(c))
34 return;
36 if (COMMANDHISTSIZE <= g_list_length(commandhistory)) {
37 /* if list is too long - remove items from beginning */
38 commandhistory = g_list_delete_link(commandhistory, g_list_first(commandhistory));
40 commandhistory = g_list_append(commandhistory, g_strdup(c));
43 gboolean
44 process_save_qmark(const char *bm, WebKitWebView *webview)
46 FILE *fp;
47 const char *filename;
48 const char *uri = webkit_web_view_get_uri(webview);
49 char qmarks[10][101];
50 char buf[100];
51 int i, mark, l=0;
52 mark = -1;
53 mark = atoi(bm);
54 if ( mark < 1 || mark > 9 ) {
55 echo_message(Error, "Invalid quickmark, only 1-9");
56 return TRUE;
58 if ( uri == NULL ) return FALSE;
59 for( i=0; i < 9; ++i ) strcpy( qmarks[i], "");
61 filename = g_strdup_printf(QUICKMARK_FILE);
63 /* get current quickmarks */
65 fp = fopen(filename, "r");
66 if (fp != NULL){
67 for( i=0; i < 10; ++i ) {
68 if (feof(fp)) {
69 break;
71 fgets(buf, 100, fp);
72 l = 0;
73 while (buf[l] && l < 100 && buf[l] != '\n') {
74 qmarks[i][l]=buf[l];
75 l++;
77 qmarks[i][l]='\0';
79 fclose(fp);
82 /* save quickmarks */
83 strcpy( qmarks[mark-1], uri );
84 fp = fopen(filename, "w");
85 g_free((gpointer *)filename);
86 if (fp == NULL) return FALSE;
87 for( i=0; i < 10; ++i )
88 fprintf(fp, "%s\n", qmarks[i]);
89 fclose(fp);
90 echo_message(Error, "Saved as quickmark %d: %s", mark, uri);
92 return TRUE;
95 void
96 make_keyslist(void)
98 int i;
99 KeyList *ptr, *current;
101 ptr = NULL;
102 current = NULL;
103 i = 0;
104 while ( keys[i].key != 0 )
106 current = malloc(sizeof(KeyList));
107 if (current == NULL) {
108 printf("Not enough memory\n");
109 exit(-1);
111 current->Element = keys[i];
112 current->next = NULL;
113 if (keylistroot == NULL) keylistroot = current;
114 if (ptr != NULL) ptr->next = current;
115 ptr = current;
116 i++;
120 gboolean
121 parse_colour(char *color) {
122 char goodcolor[8];
123 int colorlen;
125 colorlen = (int)strlen(color);
127 goodcolor[0] = '#';
128 goodcolor[7] = '\0';
130 /* help the user a bit by making string like
131 #a10 and strings like ffffff full 6digit
132 strings with # in front :)
135 if (color[0] == '#') {
136 switch (colorlen) {
137 case 7:
138 strncpy(goodcolor, color, 7);
139 break;
140 case 4:
141 goodcolor[1] = color[1];
142 goodcolor[2] = color[1];
143 goodcolor[3] = color[2];
144 goodcolor[4] = color[2];
145 goodcolor[5] = color[3];
146 goodcolor[6] = color[3];
147 break;
148 case 2:
149 goodcolor[1] = color[1];
150 goodcolor[2] = color[1];
151 goodcolor[3] = color[1];
152 goodcolor[4] = color[1];
153 goodcolor[5] = color[1];
154 goodcolor[6] = color[1];
155 break;
157 } else {
158 switch (colorlen) {
159 case 6:
160 strncpy(&goodcolor[1], color, 6);
161 break;
162 case 3:
163 goodcolor[1] = color[0];
164 goodcolor[2] = color[0];
165 goodcolor[3] = color[1];
166 goodcolor[4] = color[1];
167 goodcolor[5] = color[2];
168 goodcolor[6] = color[2];
169 break;
170 case 1:
171 goodcolor[1] = color[0];
172 goodcolor[2] = color[0];
173 goodcolor[3] = color[0];
174 goodcolor[4] = color[0];
175 goodcolor[5] = color[0];
176 goodcolor[6] = color[0];
177 break;
181 if (strlen (goodcolor) != 7) {
182 return FALSE;
183 } else {
184 strncpy(color, goodcolor, 8);
185 return TRUE;
189 gboolean
190 process_line_arg(const Arg *arg) {
191 return process_line(arg->s);
194 gboolean
195 changemapping(Key *search_key, int maprecord, char *cmd) {
196 KeyList *current, *newkey;
197 Arg a = { .s = cmd };
199 /* sanity check */
200 if (maprecord < 0 && cmd == NULL) {
201 /* possible states:
202 * - maprecord >= 0 && cmd == NULL: mapping to internal symbol
203 * - maprecord < 0 && cmd != NULL: mapping to command line
204 * - maprecord >= 0 && cmd != NULL: cmd will be ignored, treated as mapping to internal symbol
205 * - anything else (gets in here): an error, hence we return FALSE */
206 return FALSE;
209 current = keylistroot;
211 if (current)
212 while (current->next != NULL) {
213 if (
214 current->Element.mask == search_key->mask &&
215 current->Element.modkey == search_key->modkey &&
216 current->Element.key == search_key->key
218 if (maprecord >= 0) {
219 /* mapping to an internal signal */
220 current->Element.func = commands[maprecord].func;
221 current->Element.arg = commands[maprecord].arg;
222 } else {
223 /* mapping to a command line */
224 current->Element.func = process_line_arg;
225 current->Element.arg = a;
227 return TRUE;
229 current = current->next;
231 newkey = malloc(sizeof(KeyList));
232 if (newkey == NULL) {
233 printf("Not enough memory\n");
234 exit (-1);
236 newkey->Element.mask = search_key->mask;
237 newkey->Element.modkey = search_key->modkey;
238 newkey->Element.key = search_key->key;
239 if (maprecord >= 0) {
240 /* mapping to an internal signal */
241 newkey->Element.func = commands[maprecord].func;
242 newkey->Element.arg = commands[maprecord].arg;
243 } else {
244 /* mapping to a command line */
245 newkey->Element.func = process_line_arg;
246 newkey->Element.arg = a;
248 add_modkeys(newkey->Element.modkey);
250 newkey->next = NULL;
252 if (keylistroot == NULL) keylistroot = newkey;
254 if (current != NULL) current->next = newkey;
256 return TRUE;
259 void add_modkeys(char key)
261 unsigned int k, len;
262 extern char *modkeys;
263 len = strlen( modkeys );
264 while (k < len ) {
265 if ( modkeys[k] == key ) return;
266 k++;
268 modkeys = realloc(modkeys, len + 2);
269 modkeys[len] = key;
270 modkeys[len+1] = '\0';
273 gboolean
274 mappings(const Arg *arg) {
275 char line[255];
277 if (!arg->s) {
278 set_error("Missing argument.");
279 return FALSE;
281 strncpy(line, arg->s, 254);
282 if (process_map_line(line))
283 return TRUE;
284 else {
285 set_error("Invalid mapping.");
286 return FALSE;
290 int
291 get_modkey(char key) {
292 switch (key) {
293 case '1':
294 return GDK_MOD1_MASK;
295 case '2':
296 return GDK_MOD2_MASK;
297 case '3':
298 return GDK_MOD3_MASK;
299 case '4':
300 return GDK_MOD4_MASK;
301 case '5':
302 return GDK_MOD5_MASK;
303 default:
304 return FALSE;
308 gboolean
309 process_mapping(char *keystring, int maprecord, char *cmd) {
310 Key search_key;
312 search_key.mask = 0;
313 search_key.modkey = 0;
314 search_key.key = 0;
316 if (strlen(keystring) == 1) {
317 search_key.key = keystring[0];
320 if (strlen(keystring) == 2) {
321 search_key.modkey= keystring[0];
322 search_key.key = keystring[1];
325 /* process stuff like <S-v> for Shift-v or <C-v> for Ctrl-v (strlen == 5),
326 stuff like <S-v>a for Shift-v,a or <C-v>a for Ctrl-v,a (strlen == 6 && keystring[4] == '>')
327 stuff like <M1-v> for Mod1-v (strlen == 6 && keystring[5] == '>')
328 or stuff like <M1-v>a for Mod1-v,a (strlen = 7)
330 if (
331 ((strlen(keystring) == 5 || strlen(keystring) == 6) && keystring[0] == '<' && keystring[4] == '>') ||
332 ((strlen(keystring) == 6 || strlen(keystring) == 7) && keystring[0] == '<' && keystring[5] == '>')
334 switch (toupper(keystring[1])) {
335 case 'S':
336 search_key.mask = GDK_SHIFT_MASK;
337 if (strlen(keystring) == 5) {
338 keystring[3] = toupper(keystring[3]);
339 } else {
340 keystring[3] = tolower(keystring[3]);
341 keystring[5] = toupper(keystring[5]);
343 break;
344 case 'C':
345 search_key.mask = GDK_CONTROL_MASK;
346 break;
347 case 'M':
348 search_key.mask = get_modkey(keystring[2]);
349 break;
351 if (!search_key.mask)
352 return FALSE;
353 if (strlen(keystring) == 5) {
354 search_key.key = keystring[3];
355 } else if (strlen(keystring) == 7) {
356 search_key.modkey = keystring[4];
357 search_key.key = keystring[6];
358 } else {
359 if (search_key.mask == 'S' || search_key.mask == 'C') {
360 search_key.modkey = keystring[3];
361 search_key.key = keystring[5];
362 } else {
363 search_key.key = keystring[4];
368 /* process stuff like a<S-v> for a,Shift-v or a<C-v> for a,Ctrl-v (strlen == 6)
369 or stuff like a<M1-v> for a,Mod1-v (strlen == 7)
371 if (
372 (strlen(keystring) == 6 && keystring[1] == '<' && keystring[5] == '>') ||
373 (strlen(keystring) == 7 && keystring[1] == '<' && keystring[6] == '>')
375 switch (toupper(keystring[2])) {
376 case 'S':
377 search_key.mask = GDK_SHIFT_MASK;
378 keystring[4] = toupper(keystring[4]);
379 break;
380 case 'C':
381 search_key.mask = GDK_CONTROL_MASK;
382 break;
383 case 'M':
384 search_key.mask = get_modkey(keystring[3]);
385 break;
387 if (!search_key.mask)
388 return FALSE;
389 search_key.modkey= keystring[0];
390 if (strlen(keystring) == 6) {
391 search_key.key = keystring[4];
392 } else {
393 search_key.key = keystring[5];
396 return (changemapping(&search_key, maprecord, cmd));
399 gboolean
400 process_map_line(char *line) {
401 int listlen, i;
402 char *c, *cmd;
403 my_pair.line = line;
404 c = search_word(0);
406 if (!strlen(my_pair.what))
407 return FALSE;
408 while (isspace(*c) && *c)
409 c++;
411 if (*c == ':' || *c == '=')
412 c++;
413 my_pair.line = c;
414 c = search_word(1);
415 if (!strlen(my_pair.value))
416 return FALSE;
417 listlen = LENGTH(commands);
418 for (i = 0; i < listlen; i++) {
419 /* commands is fixed size */
420 if (commands[i].cmd == NULL)
421 break;
422 if (strlen(commands[i].cmd) == strlen(my_pair.value) && strncmp(commands[i].cmd, my_pair.value, strlen(my_pair.value)) == 0) {
423 /* map to an internal symbol */
424 return process_mapping(my_pair.what, i, NULL);
427 /* if this is reached, the mapping is not for one of the internal symbol - test for command line structure */
428 if (strlen(my_pair.value) > 1 && strncmp(my_pair.value, ":", 1) == 0) {
429 /* The string begins with a colon, like a command line, but it's not _just_ a colon,
430 * i.e. increasing the pointer by one will not go 'out of bounds'.
431 * We don't actually check that the command line after the = is valid.
432 * This is user responsibility, the worst case is the new mapping simply doing nothing.
433 * Since we will pass the command to the same function which also handles the config file lines,
434 * we have to strip the colon itself (a colon counts as a commented line there - like in vim).
435 * Last, but not least, the second argument being < 0 signifies to the function that this is a
436 * command line mapping, not a mapping to an existing internal symbol. */
437 cmd = (char *)malloc(sizeof(char) * strlen(my_pair.value));
438 memset(cmd, 0, strlen(my_pair.value));
439 strncpy(cmd, (my_pair.value + 1), strlen(my_pair.value) - 1);
440 return process_mapping(my_pair.what, -1, cmd);
442 return FALSE;
445 gboolean
446 build_taglist(const Arg *arg, FILE *f) {
447 int k = 0, in_tag = 0;
448 int t = 0, marker = 0;
449 char foundtab[MAXTAGSIZE+1];
450 while (arg->s[k]) {
451 if (!isspace(arg->s[k]) && !in_tag) {
452 in_tag = 1;
453 marker = k;
455 if (isspace(arg->s[k]) && in_tag) {
456 /* found a tag */
457 t = 0;
458 while (marker < k && t < MAXTAGSIZE) foundtab[t++] = arg->s[marker++];
459 foundtab[t] = '\0';
460 fprintf(f, " [%s]", foundtab);
461 in_tag = 0;
463 k++;
465 if (in_tag) {
466 t = 0;
467 while (marker < strlen(arg->s) && t < MAXTAGSIZE) foundtab[t++] = arg->s[marker++];
468 foundtab[t] = '\0';
469 fprintf(f, " [%s]", foundtab );
471 return TRUE;
474 void
475 set_error(const char *error) {
476 /* it should never happen that set_error is called more than once,
477 * but to avoid any potential memory leaks, we ignore any subsequent
478 * error if the current one has not been shown */
479 if (error_msg == NULL) {
480 error_msg = g_strdup_printf("%s", error);
484 void
485 echo_message(const MessageType type, const char *format, ...)
487 Arg a;
488 va_list ap;
490 va_start(ap, format);
491 a.i = type;
492 a.s = g_strdup_vprintf(format, ap);
493 echo(&a);
494 g_free(a.s);
495 va_end(ap);
498 Listelement *
499 complete_list(const char *searchfor, const int mode, Listelement *elementlist)
501 FILE *f;
502 const char *filename;
503 Listelement *candidatelist = NULL, *candidatepointer = NULL;
504 char s[255] = "", readelement[MAXTAGSIZE + 1] = "";
505 int i, t, n = 0;
507 if (mode == 2) {
508 /* open in history file */
509 filename = g_strdup_printf(HISTORY_STORAGE_FILENAME);
510 } else {
511 /* open in bookmark file (for tags and bookmarks) */
512 filename = g_strdup_printf(BOOKMARKS_STORAGE_FILENAME);
514 f = fopen(filename, "r");
515 if (f == NULL) {
516 g_free((gpointer *)filename);
517 return (elementlist);
520 while (fgets(s, 254, f)) {
521 if (mode == 1) {
522 /* just tags (could be more than one per line) */
523 i = 0;
524 while (s[i] && i < 254) {
525 while (s[i] != '[' && s[i])
526 i++;
527 if (s[i] != '[')
528 continue;
529 i++;
530 t = 0;
531 while (s[i] != ']' && s[i] && t < MAXTAGSIZE)
532 readelement[t++] = s[i++];
533 readelement[t] = '\0';
534 candidatelist = add_list(readelement, candidatelist);
535 i++;
537 } else {
538 /* complete string (bookmarks & history) */
539 candidatelist = add_list(s, candidatelist);
541 candidatepointer = candidatelist;
542 while (candidatepointer != NULL) {
543 strncpy(s, candidatepointer->element, sizeof(s));
544 if (!complete_case_sensitive) {
545 g_strdown(s);
547 if (!strlen(searchfor) || strstr(s, searchfor) != NULL) {
548 /* only use string up to the first space */
549 memset(readelement, 0, MAXTAGSIZE + 1);
550 if (strchr(candidatepointer->element, ' ') != NULL) {
551 i = strcspn(candidatepointer->element, " ");
552 if (i > MAXTAGSIZE)
553 i = MAXTAGSIZE;
554 strncpy(readelement, candidatepointer->element, i);
555 } else {
556 strncpy(readelement, candidatepointer->element, MAXTAGSIZE);
558 /* in the case of URLs without title, remove the line break */
559 if (readelement[strlen(readelement) - 1] == '\n') {
560 readelement[strlen(readelement) - 1] = '\0';
562 elementlist = add_list(readelement, elementlist);
563 n = count_list(elementlist);
565 if (n >= MAX_LIST_SIZE)
566 break;
567 candidatepointer = candidatepointer->next;
569 free_list(candidatelist);
570 candidatelist = NULL;
571 if (n >= MAX_LIST_SIZE)
572 break;
574 g_free((gpointer)filename);
575 return (elementlist);
578 Listelement *
579 add_list(const char *element, Listelement *elementlist)
581 int n, i = 0;
582 Listelement *newelement, *elementpointer, *lastelement;
584 if (elementlist == NULL) { /* first element */
585 newelement = malloc(sizeof(Listelement));
586 if (newelement == NULL)
587 return (elementlist);
588 strncpy(newelement->element, element, 254);
589 newelement->next = NULL;
590 return newelement;
592 elementpointer = elementlist;
593 n = strlen(element);
595 /* check if element is already in list */
596 while (elementpointer != NULL) {
597 if (strlen(elementpointer->element) == n &&
598 strncmp(elementpointer->element, element, n) == 0)
599 return (elementlist);
600 lastelement = elementpointer;
601 elementpointer = elementpointer->next;
602 i++;
604 /* add to list */
605 newelement = malloc(sizeof(Listelement));
606 if (newelement == NULL)
607 return (elementlist);
608 lastelement->next = newelement;
609 strncpy(newelement->element, element, 254);
610 newelement->next = NULL;
611 return elementlist;
614 void
615 free_list(Listelement *elementlist)
617 Listelement *elementpointer;
619 while (elementlist != NULL) {
620 elementpointer = elementlist->next;
621 free(elementlist);
622 elementlist = elementpointer;
627 count_list(Listelement *elementlist)
629 Listelement *elementpointer = elementlist;
630 int n = 0;
632 while (elementpointer != NULL) {
633 n++;
634 elementpointer = elementpointer->next;
637 return n;
640 /* split the string at the first occurence of whitespace and return the
641 * position of the second half.
642 * Unlike strtok, the substrings can be empty and the second string is
643 * stripped of trailing and leading whitespace.
644 * Return -1 if `string' contains no whitespace */
645 static int split_string_at_whitespace(char *string)
647 int index = strcspn(string, "\n\t ");
648 if (string[index] != '\0') {
649 string[index++] = 0;
650 g_strstrip(string+index);
651 return index;
653 return -1;
656 /* return TRUE, if the string contains exactly one unescaped %s and no other
657 * printf directives */
658 static gboolean sanity_check_search_url(const char *string)
660 int was_percent_char = 0, percent_s_count = 0;
662 for (; *string; string++) {
663 switch (*string) {
664 case '%':
665 was_percent_char = !was_percent_char;
666 break;
667 case 's':
668 if (was_percent_char)
669 percent_s_count++;
670 was_percent_char = 0;
671 break;
672 default:
673 if (was_percent_char)
674 return FALSE;
675 was_percent_char = 0;
676 break;
680 return !was_percent_char && percent_s_count == 1;
683 void make_searchengines_list(Searchengine *searchengines, int length)
685 int i;
686 for (i = 0; i < length; i++, searchengines++) {
687 dynamic_searchengines = g_list_prepend(dynamic_searchengines, searchengines);
691 /* find a searchengine with a given handle and return its URI or NULL if
692 * nothing is found.
693 * The returned string is internal and must not be freed or modified. */
694 char *find_uri_for_searchengine(const char *handle)
696 GList *l;
698 if (dynamic_searchengines != NULL) {
699 for (l = dynamic_searchengines; l; l = g_list_next(l)) {
700 Searchengine *s = (Searchengine*)l->data;
701 if (!strcmp(s->handle, handle)) {
702 return s->uri;
707 return NULL;
710 enum ConfigFileError
711 read_rcfile(const char *config)
713 int t, linum = 0, index;
714 char s[255], *buffer;
715 FILE *fpin;
716 gboolean found_malformed_lines = FALSE;
717 Searchengine *new;
718 URIHandler *newhandler;
720 if (access(config, F_OK) != 0)
721 return FILE_NOT_FOUND;
723 fpin = fopen(config, "r");
724 if (fpin == NULL)
725 return READING_FAILED;
727 while (fgets(s, 254, fpin)) {
728 linum++;
730 * ignore lines that begin with #, / and such
732 if (!isalpha(s[0]))
733 continue;
734 t = strlen(s);
735 s[t - 1] = '\0';
736 if (strncmp(s, "searchengine", 12) == 0) {
737 buffer = (s + 12);
738 while (buffer[0] == ' ')
739 buffer++;
740 /* split line at whitespace */
741 index = split_string_at_whitespace(buffer);
742 if (index < 0 || buffer[0] == '\0' || buffer[index] == '\0'
743 || !sanity_check_search_url(buffer+index)) {
744 fprintf(stderr, "searchengines: syntax error on line %d\n", linum);
745 found_malformed_lines = TRUE;
746 continue;
748 new = malloc(sizeof(Searchengine));
749 if (new == NULL) {
750 fprintf(stderr, "Memory exhausted while loading search engines.\n");
751 exit(EXIT_FAILURE);
753 new->handle = g_strdup(buffer);
754 new->uri = g_strdup(buffer+index);
755 dynamic_searchengines = g_list_prepend(dynamic_searchengines, new);
756 } else if (strncmp(s, "handler", 7) == 0) {
757 buffer = (s + 7);
758 while (buffer[0] == ' ')
759 buffer++;
760 /* split line at whitespace */
761 index = split_string_at_whitespace(buffer);
762 if (index < 0 || buffer[0] == '\0' || buffer[index] == '\0'
763 || !sanity_check_search_url(buffer+index)) { /* this sanity check is also valid for handler definitions */
764 fprintf(stderr, "URI handlers: syntax error on line %d\n", linum);
765 found_malformed_lines = TRUE;
766 continue;
768 newhandler = malloc(sizeof(URIHandler));
769 if (newhandler == NULL) {
770 fprintf(stderr, "Memory exhausted while loading uri handlers.\n");
771 exit(EXIT_FAILURE);
773 newhandler->handle = g_strdup(buffer);
774 newhandler->handler = g_strdup(buffer+index);
775 dynamic_uri_handlers = g_list_prepend(dynamic_uri_handlers, newhandler);
776 } else {
777 if (!process_line(s))
778 found_malformed_lines = TRUE;
781 fclose(fpin);
782 return found_malformed_lines ? SYNTAX_ERROR : SUCCESS;
785 void make_uri_handlers_list(URIHandler *uri_handlers, int length)
787 int i;
788 for (i = 0; i < length; i++, uri_handlers++) {
789 dynamic_uri_handlers = g_list_prepend(dynamic_uri_handlers, uri_handlers);
794 /* spawn a child process handling a protocol encoded in URI.
796 On success, pid will contain the pid of the spawned child.
797 If you pass NULL as child_pid, glib will reap the child. */
798 gboolean
799 open_handler_pid(char *uri, GPid *child_pid) {
800 char *argv[64];
801 char *p = NULL, *arg, arg_temp[MAX_SETTING_SIZE], *temp, temp2[MAX_SETTING_SIZE] = "", *temp3;
802 int j;
803 GList *l;
804 GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
806 if (child_pid) {
807 flags |= G_SPAWN_DO_NOT_REAP_CHILD;
809 p = strchr(uri, ':');
810 if (p) {
811 if (dynamic_uri_handlers != NULL) {
812 for (l = dynamic_uri_handlers; l; l = g_list_next(l)) {
813 URIHandler *s = (URIHandler *)l->data;
814 if (strlen(uri) >= strlen(s->handle) && strncmp(s->handle, uri, strlen(s->handle)) == 0) {
815 if (strlen(s->handler) > 0) {
816 arg = (uri + strlen(s->handle));
817 strncpy(temp2, s->handler, MAX_SETTING_SIZE);
818 temp = strtok(temp2, " ");
819 j = 0;
820 while (temp != NULL) {
821 if (strstr(temp, "%s")) {
822 temp3 = temp;
823 memset(arg_temp, 0, MAX_SETTING_SIZE);
824 while (strncmp(temp3, "%s", 2) != 0) {
825 strncat(arg_temp, temp3, 1);
826 temp3++;
828 strcat(arg_temp, arg);
829 temp3++;
830 temp3++;
831 strcat(arg_temp, temp3);
832 argv[j] = arg_temp;
833 } else {
834 argv[j] = temp;
836 temp = strtok(NULL, " ");
837 j++;
839 argv[j] = NULL;
840 g_spawn_async(NULL, argv, NULL, flags,
841 NULL, NULL, child_pid, NULL);
843 return TRUE;
848 return FALSE;
852 gboolean
853 open_handler(char *uri) {
854 return open_handler_pid(uri, NULL);