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