|
|
bf3226 |
commit 7b7d83c571ceb3050969359817d4145600f14ae8
|
|
|
bf3226 |
Author: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
|
bf3226 |
Date: Fri Apr 9 17:07:31 2021 +0200
|
|
|
bf3226 |
|
|
|
bf3226 |
Check CKF_LIBRARY_CANT_CREATE_OS_THREADS at C_Initialize
|
|
|
bf3226 |
|
|
|
bf3226 |
Fail if flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set at C_Initialize,
|
|
|
bf3226 |
and event support is enabled (this is the default). We need to use pthreads
|
|
|
bf3226 |
for the event thread, so we can't work if CKF_LIBRARY_CANT_CREATE_OS_THREADS
|
|
|
bf3226 |
is set. Fail with CKR_NEED_TO_CREATE_THREADS if so.
|
|
|
bf3226 |
|
|
|
bf3226 |
The event support can be globally disabled using keyword 'disable-event-support'
|
|
|
bf3226 |
in opencryptoki.conf. This disables pkcsslots to accept admin connections,
|
|
|
bf3226 |
and it does not monitor for AP UDEV events (on s390 platform). No event
|
|
|
bf3226 |
thread is started in the opencryptoki processes, thus we can accept if flag
|
|
|
bf3226 |
CKF_LIBRARY_CANT_CREATE_OS_THREADS is set in that case.
|
|
|
bf3226 |
|
|
|
bf3226 |
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
|
|
bf3226 |
|
|
|
bf3226 |
diff --git a/man/man5/opencryptoki.conf.5.in b/man/man5/opencryptoki.conf.5.in
|
|
|
bf3226 |
index 71218f79..7dc676ab 100644
|
|
|
bf3226 |
--- a/man/man5/opencryptoki.conf.5.in
|
|
|
bf3226 |
+++ b/man/man5/opencryptoki.conf.5.in
|
|
|
bf3226 |
@@ -10,8 +10,16 @@ pkcs#11 slots. At startup, the pkcsslotd daemon parses this file to
|
|
|
bf3226 |
determine which slots will be made available.
|
|
|
bf3226 |
|
|
|
bf3226 |
.SH SYNTAX
|
|
|
bf3226 |
-This file is made up of slot descriptions. Each slot description
|
|
|
bf3226 |
-is composed of a slot number, brackets and key-value pairs.
|
|
|
bf3226 |
+This file is made up of optional global definitions, and slot descriptions.
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+The following global definitions are valid:
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+.TP
|
|
|
bf3226 |
+.BR disable-event-support
|
|
|
bf3226 |
+If this keyword is specified the openCryptoki event support is disabled.
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+.P
|
|
|
bf3226 |
+Each slot description is composed of a slot number, brackets and key-value pairs.
|
|
|
bf3226 |
|
|
|
bf3226 |
slot number
|
|
|
bf3226 |
{
|
|
|
bf3226 |
diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h
|
|
|
bf3226 |
index e37368a5..451a8cf1 100644
|
|
|
bf3226 |
--- a/usr/include/slotmgr.h
|
|
|
bf3226 |
+++ b/usr/include/slotmgr.h
|
|
|
bf3226 |
@@ -99,6 +99,7 @@ typedef struct {
|
|
|
bf3226 |
LW_SHM_TYPE *shm_addr; // token specific shm address
|
|
|
bf3226 |
} Slot_Info_t;
|
|
|
bf3226 |
|
|
|
bf3226 |
+#define FLAG_EVENT_SUPPORT_DISABLED 0x01
|
|
|
bf3226 |
|
|
|
bf3226 |
#ifdef PKCS64
|
|
|
bf3226 |
|
|
|
bf3226 |
@@ -200,6 +201,7 @@ typedef struct {
|
|
|
bf3226 |
|
|
|
bf3226 |
typedef struct {
|
|
|
bf3226 |
uint8 num_slots;
|
|
|
bf3226 |
+ uint8 flags;
|
|
|
bf3226 |
CK_INFO_64 ck_info;
|
|
|
bf3226 |
Slot_Info_t_64 slot_info[NUMBER_SLOTS_MANAGED];
|
|
|
bf3226 |
} Slot_Mgr_Socket_t;
|
|
|
bf3226 |
@@ -214,6 +216,7 @@ typedef struct {
|
|
|
bf3226 |
|
|
|
bf3226 |
typedef struct {
|
|
|
bf3226 |
uint8 num_slots;
|
|
|
bf3226 |
+ uint8 flags;
|
|
|
bf3226 |
CK_INFO ck_info;
|
|
|
bf3226 |
Slot_Info_t slot_info[NUMBER_SLOTS_MANAGED];
|
|
|
bf3226 |
} Slot_Mgr_Socket_t;
|
|
|
bf3226 |
diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c
|
|
|
bf3226 |
index 2873a20a..6517ca6c 100644
|
|
|
bf3226 |
--- a/usr/lib/api/api_interface.c
|
|
|
bf3226 |
+++ b/usr/lib/api/api_interface.c
|
|
|
bf3226 |
@@ -308,7 +308,8 @@ void parent_fork_after()
|
|
|
bf3226 |
return;
|
|
|
bf3226 |
|
|
|
bf3226 |
/* Restart the event thread in the parent when fork is complete */
|
|
|
bf3226 |
- if (Anchor->event_thread == 0)
|
|
|
bf3226 |
+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
|
|
|
bf3226 |
+ Anchor->event_thread == 0)
|
|
|
bf3226 |
start_event_thread();
|
|
|
bf3226 |
}
|
|
|
bf3226 |
|
|
|
bf3226 |
@@ -2752,13 +2753,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
|
|
|
bf3226 |
goto error;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
}
|
|
|
bf3226 |
- // If we EVER need to create threads from this library we must
|
|
|
bf3226 |
- // check the Flags for the Can_Create_OS_Threads flag
|
|
|
bf3226 |
- // Right now the library DOES NOT create threads and therefore this
|
|
|
bf3226 |
- // check is irrelavant.
|
|
|
bf3226 |
- if (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
|
|
|
bf3226 |
- TRACE_DEVEL("Can't create OS threads...This is OK\n");
|
|
|
bf3226 |
- }
|
|
|
bf3226 |
+
|
|
|
bf3226 |
// Since this is an initialization path, we will be verbose in the
|
|
|
bf3226 |
// code rather than efficient.
|
|
|
bf3226 |
//
|
|
|
bf3226 |
@@ -2848,7 +2843,21 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
|
|
|
bf3226 |
rc = CKR_FUNCTION_FAILED;
|
|
|
bf3226 |
goto error_shm;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
- // Initialize structure values
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+ if (pVoid != NULL) {
|
|
|
bf3226 |
+ pArg = (CK_C_INITIALIZE_ARGS *) pVoid;
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
|
|
|
bf3226 |
+ (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) != 0) {
|
|
|
bf3226 |
+ TRACE_ERROR("Flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set and "
|
|
|
bf3226 |
+ "event support is enabled\n");
|
|
|
bf3226 |
+ OCK_SYSLOG(LOG_ERR, "C_Initialize: Application specified that "
|
|
|
bf3226 |
+ "library can't create OS threads. PKCS11 Module requires "
|
|
|
bf3226 |
+ "to create threads when event support is enabled.\n");
|
|
|
bf3226 |
+ rc = CKR_NEED_TO_CREATE_THREADS;
|
|
|
bf3226 |
+ goto error;
|
|
|
bf3226 |
+ }
|
|
|
bf3226 |
+ }
|
|
|
bf3226 |
|
|
|
bf3226 |
//Register with pkcsslotd
|
|
|
bf3226 |
if (!API_Register()) {
|
|
|
bf3226 |
@@ -2867,7 +2876,8 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
|
|
|
bf3226 |
}
|
|
|
bf3226 |
|
|
|
bf3226 |
/* Start event receiver thread */
|
|
|
bf3226 |
- if (start_event_thread() != 0) {
|
|
|
bf3226 |
+ if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
|
|
|
bf3226 |
+ start_event_thread() != 0) {
|
|
|
bf3226 |
TRACE_ERROR("Failed to start event thread\n");
|
|
|
bf3226 |
|
|
|
bf3226 |
// unload all the STDLL's from the application
|
|
|
bf3226 |
diff --git a/usr/lib/common/configparser.h b/usr/lib/common/configparser.h
|
|
|
bf3226 |
index 13ca648d..b3c32496 100644
|
|
|
bf3226 |
--- a/usr/lib/common/configparser.h
|
|
|
bf3226 |
+++ b/usr/lib/common/configparser.h
|
|
|
bf3226 |
@@ -35,6 +35,7 @@ typedef int (*end_slot_f)(void *private);
|
|
|
bf3226 |
typedef int (*key_str_f)(void *private, int tok, const char *val);
|
|
|
bf3226 |
typedef int (*key_vers_f)(void *private, int tok, unsigned int vers);
|
|
|
bf3226 |
typedef void (*eolcomment_f)(void *private, const char *comment);
|
|
|
bf3226 |
+typedef void (*disab_event_supp_f)(void *private);
|
|
|
bf3226 |
/*
|
|
|
bf3226 |
* Report an error. If the error is not reported by the parser itself
|
|
|
bf3226 |
* but via one of the parse functions, \c parsermsg will be \c NULL.
|
|
|
bf3226 |
@@ -52,6 +53,7 @@ typedef void (*error_f)(void *private, int line, const char *parsermsg);
|
|
|
bf3226 |
*/
|
|
|
bf3226 |
struct parsefuncs {
|
|
|
bf3226 |
ockversion_f version;
|
|
|
bf3226 |
+ disab_event_supp_f disab_event_supp;
|
|
|
bf3226 |
eol_f eol;
|
|
|
bf3226 |
begin_slot_f begin_slot;
|
|
|
bf3226 |
end_slot_f end_slot;
|
|
|
bf3226 |
diff --git a/usr/lib/common/lexer.l b/usr/lib/common/lexer.l
|
|
|
bf3226 |
index b35a0b72..38cbcb70 100644
|
|
|
bf3226 |
--- a/usr/lib/common/lexer.l
|
|
|
bf3226 |
+++ b/usr/lib/common/lexer.l
|
|
|
bf3226 |
@@ -69,6 +69,7 @@ extern char *configparse_strdup(const char *s);
|
|
|
bf3226 |
|
|
|
bf3226 |
version return OCKVERSION;
|
|
|
bf3226 |
slot return SLOT;
|
|
|
bf3226 |
+disable-event-support return DISABLE_EVENT_SUPPORT;
|
|
|
bf3226 |
|
|
|
bf3226 |
[^\"= \t\n]+ {
|
|
|
bf3226 |
yylval.str = configparse_strdup(yytext);
|
|
|
bf3226 |
diff --git a/usr/lib/common/parser.y b/usr/lib/common/parser.y
|
|
|
bf3226 |
index 86806fcb..40c3994d 100644
|
|
|
bf3226 |
--- a/usr/lib/common/parser.y
|
|
|
bf3226 |
+++ b/usr/lib/common/parser.y
|
|
|
bf3226 |
@@ -65,7 +65,7 @@ int lookup_keyword(const char *key);
|
|
|
bf3226 |
int err;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
|
|
|
bf3226 |
-%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF
|
|
|
bf3226 |
+%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF DISABLE_EVENT_SUPPORT
|
|
|
bf3226 |
%token <str> STRING
|
|
|
bf3226 |
%token <str> KEYWORD
|
|
|
bf3226 |
%token <num> INTEGER
|
|
|
bf3226 |
@@ -81,6 +81,7 @@ config_file:
|
|
|
bf3226 |
|
|
|
bf3226 |
sections:
|
|
|
bf3226 |
version_def eolcomment
|
|
|
bf3226 |
+ | disable_event_support_def eolcomment
|
|
|
bf3226 |
| SLOT INTEGER BEGIN_DEF
|
|
|
bf3226 |
{
|
|
|
bf3226 |
if (parsefuncs->begin_slot && parsefuncs->begin_slot(parsedata, $2, 0)) {
|
|
|
bf3226 |
@@ -125,6 +126,13 @@ version_def:
|
|
|
bf3226 |
}
|
|
|
bf3226 |
configparse_freestringsfrom($2);
|
|
|
bf3226 |
}
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+disable_event_support_def:
|
|
|
bf3226 |
+ DISABLE_EVENT_SUPPORT
|
|
|
bf3226 |
+ {
|
|
|
bf3226 |
+ if (parsefuncs->disab_event_supp)
|
|
|
bf3226 |
+ parsefuncs->disab_event_supp(parsedata);
|
|
|
bf3226 |
+ }
|
|
|
bf3226 |
|
|
|
bf3226 |
line_def:
|
|
|
bf3226 |
STRING EQUAL TOKVERSION
|
|
|
bf3226 |
diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h
|
|
|
bf3226 |
index d7edcb3c..1dd0bac9 100644
|
|
|
bf3226 |
--- a/usr/sbin/pkcsslotd/pkcsslotd.h
|
|
|
bf3226 |
+++ b/usr/sbin/pkcsslotd/pkcsslotd.h
|
|
|
bf3226 |
@@ -88,7 +88,7 @@ int XProcLock(void);
|
|
|
bf3226 |
int XProcUnLock(void);
|
|
|
bf3226 |
int CreateXProcLock(void);
|
|
|
bf3226 |
|
|
|
bf3226 |
-int init_socket_server();
|
|
|
bf3226 |
+int init_socket_server(int event_support_disabled);
|
|
|
bf3226 |
int term_socket_server();
|
|
|
bf3226 |
int init_socket_data(Slot_Mgr_Socket_t *sp);
|
|
|
bf3226 |
int socket_connection_handler(int timeout_secs);
|
|
|
bf3226 |
diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c
|
|
|
bf3226 |
index efbfe8fd..3b328a6c 100644
|
|
|
bf3226 |
--- a/usr/sbin/pkcsslotd/slotmgr.c
|
|
|
bf3226 |
+++ b/usr/sbin/pkcsslotd/slotmgr.c
|
|
|
bf3226 |
@@ -34,6 +34,7 @@ int shmid;
|
|
|
bf3226 |
key_t tok;
|
|
|
bf3226 |
Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED];
|
|
|
bf3226 |
unsigned int NumberSlotsInDB = 0;
|
|
|
bf3226 |
+int event_support_disabled = 0;
|
|
|
bf3226 |
|
|
|
bf3226 |
Slot_Info_t_64 *psinfo;
|
|
|
bf3226 |
|
|
|
bf3226 |
@@ -467,6 +468,13 @@ static int slotmgr_key_vers(void *private, int tok, unsigned int vers)
|
|
|
bf3226 |
return 1;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
|
|
|
bf3226 |
+static void slotmgr_disab_event_supp(void *private)
|
|
|
bf3226 |
+{
|
|
|
bf3226 |
+ UNUSED(private);
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+ event_support_disabled = 1;
|
|
|
bf3226 |
+}
|
|
|
bf3226 |
+
|
|
|
bf3226 |
static void slotmgr_parseerror(void *private, int line, const char *parsermsg)
|
|
|
bf3226 |
{
|
|
|
bf3226 |
struct parse_data *d = (struct parse_data *)private;
|
|
|
bf3226 |
@@ -480,6 +488,7 @@ static struct parsefuncs slotmgr_parsefuncs = {
|
|
|
bf3226 |
.end_slot = slotmgr_end_slot,
|
|
|
bf3226 |
.key_str = slotmgr_key_str,
|
|
|
bf3226 |
.key_vers = slotmgr_key_vers,
|
|
|
bf3226 |
+ .disab_event_supp = slotmgr_disab_event_supp,
|
|
|
bf3226 |
.parseerror = slotmgr_parseerror
|
|
|
bf3226 |
};
|
|
|
bf3226 |
|
|
|
bf3226 |
@@ -568,7 +577,7 @@ int main(int argc, char *argv[], char *envp[])
|
|
|
bf3226 |
if (!XProcUnLock())
|
|
|
bf3226 |
return 4;
|
|
|
bf3226 |
|
|
|
bf3226 |
- if (!init_socket_server()) {
|
|
|
bf3226 |
+ if (!init_socket_server(event_support_disabled)) {
|
|
|
bf3226 |
DestroyMutexes();
|
|
|
bf3226 |
DetachFromSharedMemory();
|
|
|
bf3226 |
DestroySharedMemory();
|
|
|
bf3226 |
@@ -582,6 +591,8 @@ int main(int argc, char *argv[], char *envp[])
|
|
|
bf3226 |
DestroySharedMemory();
|
|
|
bf3226 |
return 6;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
+ if (event_support_disabled)
|
|
|
bf3226 |
+ socketData.flags |= FLAG_EVENT_SUPPORT_DISABLED;
|
|
|
bf3226 |
|
|
|
bf3226 |
/* Create customized token directories */
|
|
|
bf3226 |
psinfo = &socketData.slot_info[0];
|
|
|
bf3226 |
diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c
|
|
|
bf3226 |
index 41408670..3aa40267 100644
|
|
|
bf3226 |
--- a/usr/sbin/pkcsslotd/socket_server.c
|
|
|
bf3226 |
+++ b/usr/sbin/pkcsslotd/socket_server.c
|
|
|
bf3226 |
@@ -139,12 +139,12 @@ struct event_info {
|
|
|
bf3226 |
};
|
|
|
bf3226 |
|
|
|
bf3226 |
static int epoll_fd = -1;
|
|
|
bf3226 |
-static struct listener_info proc_listener;
|
|
|
bf3226 |
+static struct listener_info proc_listener = { .socket = -1 };
|
|
|
bf3226 |
static DL_NODE *proc_connections = NULL;
|
|
|
bf3226 |
-static struct listener_info admin_listener;
|
|
|
bf3226 |
+static struct listener_info admin_listener = { .socket = -1 };
|
|
|
bf3226 |
static DL_NODE *admin_connections = NULL;
|
|
|
bf3226 |
#ifdef WITH_LIBUDEV
|
|
|
bf3226 |
-static struct udev_mon udev_mon;
|
|
|
bf3226 |
+static struct udev_mon udev_mon = { .socket = -1 };
|
|
|
bf3226 |
#endif
|
|
|
bf3226 |
static DL_NODE *pending_events = NULL;
|
|
|
bf3226 |
static unsigned long pending_events_count = 0;
|
|
|
bf3226 |
@@ -1620,6 +1620,9 @@ static void udev_mon_term(struct udev_mon *udev_mon)
|
|
|
bf3226 |
if (udev_mon == NULL)
|
|
|
bf3226 |
return;
|
|
|
bf3226 |
|
|
|
bf3226 |
+ if (udev_mon->socket < 0)
|
|
|
bf3226 |
+ return;
|
|
|
bf3226 |
+
|
|
|
bf3226 |
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, udev_mon->socket, NULL);
|
|
|
bf3226 |
if (udev_mon->udev != NULL)
|
|
|
bf3226 |
udev_unref(udev_mon->udev);
|
|
|
bf3226 |
@@ -1636,6 +1639,7 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData)
|
|
|
bf3226 |
{
|
|
|
bf3226 |
unsigned int processed = 0;
|
|
|
bf3226 |
|
|
|
bf3226 |
+ socketData->flags = 0;
|
|
|
bf3226 |
PopulateCKInfo(&(socketData->ck_info));
|
|
|
bf3226 |
socketData->num_slots = NumberSlotsInDB;
|
|
|
bf3226 |
PopulateSlotInfo(socketData->slot_info, &processed);
|
|
|
bf3226 |
@@ -1692,7 +1696,7 @@ int socket_connection_handler(int timeout_secs)
|
|
|
bf3226 |
return TRUE;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
|
|
|
bf3226 |
-int init_socket_server()
|
|
|
bf3226 |
+int init_socket_server(int event_support_disabled)
|
|
|
bf3226 |
{
|
|
|
bf3226 |
int err;
|
|
|
bf3226 |
|
|
|
bf3226 |
@@ -1710,18 +1714,20 @@ int init_socket_server()
|
|
|
bf3226 |
return FALSE;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
|
|
|
bf3226 |
- if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener,
|
|
|
bf3226 |
- admin_new_conn, NUMBER_ADMINS_ALLOWED)) {
|
|
|
bf3226 |
- term_socket_server();
|
|
|
bf3226 |
- return FALSE;
|
|
|
bf3226 |
- }
|
|
|
bf3226 |
+ if (!event_support_disabled) {
|
|
|
bf3226 |
+ if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener,
|
|
|
bf3226 |
+ admin_new_conn, NUMBER_ADMINS_ALLOWED)) {
|
|
|
bf3226 |
+ term_socket_server();
|
|
|
bf3226 |
+ return FALSE;
|
|
|
bf3226 |
+ }
|
|
|
bf3226 |
|
|
|
bf3226 |
#ifdef WITH_LIBUDEV
|
|
|
bf3226 |
- if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) {
|
|
|
bf3226 |
- term_socket_server();
|
|
|
bf3226 |
- return FALSE;
|
|
|
bf3226 |
- }
|
|
|
bf3226 |
+ if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) {
|
|
|
bf3226 |
+ term_socket_server();
|
|
|
bf3226 |
+ return FALSE;
|
|
|
bf3226 |
+ }
|
|
|
bf3226 |
#endif
|
|
|
bf3226 |
+ }
|
|
|
bf3226 |
|
|
|
bf3226 |
DbgLog(DL0, "%s: Socket server started", __func__);
|
|
|
bf3226 |
|
|
|
bf3226 |
diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
|
|
|
bf3226 |
index 7c225730..94fd1196 100644
|
|
|
bf3226 |
--- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
|
|
|
bf3226 |
+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
|
|
|
bf3226 |
@@ -2066,6 +2066,13 @@ static int parseupdate_ockversion(void *private, const char *version)
|
|
|
bf3226 |
return 0;
|
|
|
bf3226 |
}
|
|
|
bf3226 |
|
|
|
bf3226 |
+static void parseupdate_disab_event_supp(void *private)
|
|
|
bf3226 |
+{
|
|
|
bf3226 |
+ struct parseupdate *u = (struct parseupdate *)private;
|
|
|
bf3226 |
+
|
|
|
bf3226 |
+ fprintf(u->f, "disable-event-support");
|
|
|
bf3226 |
+}
|
|
|
bf3226 |
+
|
|
|
bf3226 |
static void parseupdate_eol(void *private)
|
|
|
bf3226 |
{
|
|
|
bf3226 |
struct parseupdate *u = (struct parseupdate *)private;
|
|
|
bf3226 |
@@ -2124,6 +2131,7 @@ static void parseupdate_eolcomment(void *private, const char *comment)
|
|
|
bf3226 |
|
|
|
bf3226 |
static struct parsefuncs parseupdatefuncs = {
|
|
|
bf3226 |
.version = parseupdate_ockversion,
|
|
|
bf3226 |
+ .disab_event_supp = parseupdate_disab_event_supp,
|
|
|
bf3226 |
.eol = parseupdate_eol,
|
|
|
bf3226 |
.begin_slot = parseupdate_begin_slot,
|
|
|
bf3226 |
.end_slot = parseupdate_end_slot,
|