Changeset View
Changeset View
Standalone View
Standalone View
contrib/mg/autoexec.c
- This file was added.
/* $OpenBSD: autoexec.c,v 1.18 2021/04/21 14:45:28 lum 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. | |||||
*/ | |||||
/* ARGSUSED */ | |||||
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); | |||||
} |