xref: /openbsd-src/usr.bin/mg/autoexec.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /* $OpenBSD: autoexec.c,v 1.14 2007/02/08 21:40:03 kjell Exp $ */
2 /* this file is in the public domain */
3 /* Author: Vincent Labrecque <vincent@openbsd.org>	April 2002 */
4 
5 #include "def.h"
6 #include "funmap.h"
7 
8 #include <fnmatch.h>
9 
10 struct autoexec {
11 	SLIST_ENTRY(autoexec) next;	/* link in the linked list */
12 	const char	*pattern;	/* Pattern to match to filenames */
13 	PF		 fp;
14 };
15 
16 static SLIST_HEAD(, autoexec)	 autos;
17 static int			 ready;
18 
19 
20 #define AUTO_GROW 8
21 /*
22  * Return a NULL terminated array of function pointers to be called
23  * when we open a file that matches <fname>.  The list must be free(ed)
24  * after use.
25  */
26 PF *
27 find_autoexec(const char *fname)
28 {
29 	PF		*pfl, *npfl;
30 	int		 have, used;
31 	struct autoexec *ae;
32 
33 	if (!ready)
34 		return (NULL);
35 
36 	pfl = NULL;
37 	have = 0;
38 	used = 0;
39 	SLIST_FOREACH(ae, &autos, next) {
40 		if (fnmatch(ae->pattern, fname, 0) == 0) {
41 			if (used >= have) {
42 				npfl = realloc(pfl, (have + AUTO_GROW + 1) *
43 				    sizeof(PF));
44 				if (npfl == NULL)
45 					panic("out of memory");
46 				pfl = npfl;
47 				have += AUTO_GROW;
48 			}
49 			pfl[used++] = ae->fp;
50 		}
51 	}
52 	if (used)
53 		pfl[used] = NULL;
54 
55 	return (pfl);
56 }
57 
58 int
59 add_autoexec(const char *pattern, const char *func)
60 {
61 	PF		 fp;
62 	struct autoexec *ae;
63 
64 	if (!ready) {
65 		SLIST_INIT(&autos);
66 		ready = 1;
67 	}
68 	fp = name_function(func);
69 	if (fp == NULL)
70 		return (FALSE);
71 	ae = malloc(sizeof(*ae));
72 	if (ae == NULL)
73 		return (FALSE);
74 	ae->fp = fp;
75 	ae->pattern = strdup(pattern);
76 	if (ae->pattern == NULL) {
77 		free(ae);
78 		return (FALSE);
79 	}
80 	SLIST_INSERT_HEAD(&autos, ae, next);
81 
82 	return (TRUE);
83 }
84 
85 /*
86  * Register an auto-execute hook; that is, specify a filename pattern
87  * (conforming to the shell's filename globbing rules) and an associated
88  * function to execute when a file matching the specified pattern
89  * is read into a buffer.
90 */
91 /* ARGSUSED */
92 int
93 auto_execute(int f, int n)
94 {
95 	char	patbuf[128], funcbuf[128], *patp, *funcp;
96 	int	s;
97 
98 	if ((patp = eread("Filename pattern: ", patbuf, sizeof(patbuf),
99 	    EFNEW | EFCR)) == NULL)
100 		return (ABORT);
101 	else if (patp[0] == '\0')
102 		return (FALSE);
103 	if ((funcp = eread("Execute: ", funcbuf, sizeof(funcbuf),
104 	    EFNEW | EFCR | EFFUNC)) == NULL)
105 		return (ABORT);
106 	else if (funcp[0] == '\0')
107 		return (FALSE);
108 	if ((s = add_autoexec(patp, funcp)) != TRUE)
109 		return (s);
110 	return (TRUE);
111 }
112