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