jcs's openbsd hax
openbsd
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
15struct 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
21static SLIST_HEAD(, autoexec) autos;
22static 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 */
31PF *
32find_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
63int
64add_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*/
96int
97auto_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}