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 * 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 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 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