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