opensc-notify: notify for card events
... manually or in daemon mode fixes compilation in MinGW/Travis CI
This commit is contained in:
parent
b2cde0f7fb
commit
ce3f27ff54
|
@ -63,7 +63,7 @@ before_script:
|
|||
fi
|
||||
- ./bootstrap
|
||||
- if [ -z "$HOST" ]; then
|
||||
CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui;
|
||||
CFLAGS="-Werror" ./configure $ENABLE_DOC --enable-dnie-ui --disable-notify;
|
||||
else
|
||||
if [ ! -f "$(winepath 'C:/Program Files (x86)/Inno Setup 5/ISCC.exe')" ]; then
|
||||
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16;
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
do shell script "killall opensc-notify || true"
|
||||
do shell script "nohup /Library/OpenSC/bin/opensc-notify > /dev/null 2>&1 &"
|
|
@ -108,6 +108,8 @@ if ! test -e NotificationProxy; then
|
|||
git clone http://github.com/frankmorgner/NotificationProxy.git
|
||||
fi
|
||||
xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/
|
||||
mkdir -p "$BUILDPATH/target/Applications"
|
||||
osacompile -o "$BUILDPATH/target/Applications/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript"
|
||||
|
||||
# Prepare target root
|
||||
# The "UnInstaller"
|
||||
|
|
|
@ -16,6 +16,7 @@ rm -f /usr/local/lib/opensc-pkcs11.so
|
|||
rm -f /usr/local/lib/onepin-opensc-pkcs11.so
|
||||
|
||||
# Remove installed files
|
||||
rm -rf "/Applications/OpenSC Notify.app"
|
||||
rm -rf /Library/OpenSC
|
||||
rm -rf /Library/Security/tokend/OpenSC.tokend
|
||||
rm -rf /System/Library/Security/tokend/OpenSC.tokend
|
||||
|
|
|
@ -133,6 +133,9 @@ case "${host}" in
|
|||
;;
|
||||
esac
|
||||
|
||||
AX_CHECK_COMPILE_FLAG(-Wno-error=unused-but-set-variable, [have_unused_but_set_variable="yes"], [have_unused_but_set_variable="no"], [-Werror -Wunknown-warning-option])
|
||||
AM_CONDITIONAL([HAVE_UNUSED_BUT_SET_VARIABLE], [test "${have_unused_but_set_variable}" = "yes"])
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[strict],
|
||||
[AS_HELP_STRING([--disable-strict],[disable strict compile mode @<:@disabled@:>@])],
|
||||
|
@ -384,7 +387,7 @@ AC_FUNC_VPRINTF
|
|||
AC_CHECK_FUNCS([ \
|
||||
getpass gettimeofday getline memset mkdir \
|
||||
strdup strerror getopt_long getopt_long_only \
|
||||
strlcpy strlcat strnlen
|
||||
strlcpy strlcat strnlen sigaction
|
||||
])
|
||||
AC_CHECK_SIZEOF(void *)
|
||||
if test "${ac_cv_sizeof_void_p}" = 8; then
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check whether the given FLAG works with the current language's compiler
|
||||
# or gives an error. (Warnings, however, are ignored)
|
||||
#
|
||||
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||
# success/failure.
|
||||
#
|
||||
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||
# force the compiler to issue an error when a bad flag is given.
|
||||
#
|
||||
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
|
||||
#
|
||||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||
# gives unlimited permission to copy, distribute and modify the configure
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 5
|
||||
|
||||
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
|
||||
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
|
||||
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||
[AS_VAR_SET(CACHEVAR,[no])])
|
||||
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||
AS_VAR_IF(CACHEVAR,yes,
|
||||
[m4_default([$2], :)],
|
||||
[m4_default([$3], :)])
|
||||
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||
])dnl AX_CHECK_COMPILE_FLAGS
|
|
@ -12,14 +12,16 @@ do_subst = $(SED) \
|
|||
-e 's,[@]X509DIR[@],$(X509DIR),g'
|
||||
|
||||
NPA_TOOL_BUILT_SOURCES = npa-tool-cmdline.h npa-tool-cmdline.c
|
||||
OPENSC_NOTIFY_BUILT_SOURCES = opensc-notify-cmdline.h opensc-notify-cmdline.c
|
||||
|
||||
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/versioninfo-tools.rc
|
||||
EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in npa-tool.ggo.in npa-tool.1
|
||||
EXTRA_DIST = Makefile.mak versioninfo-tools.rc.in npa-tool.ggo.in npa-tool.1 opensc-notify.ggo.in
|
||||
|
||||
noinst_HEADERS = util.h fread_to_eof.h
|
||||
noinst_PROGRAMS = sceac-example
|
||||
bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \
|
||||
pkcs11-tool cardos-tool eidenv openpgp-tool iasecc-tool opensc-notify
|
||||
bin_PROGRAMS = opensc-tool opensc-explorer opensc-notify \
|
||||
pkcs15-tool pkcs15-crypt pkcs11-tool \
|
||||
cardos-tool eidenv openpgp-tool iasecc-tool
|
||||
if ENABLE_OPENSSL
|
||||
bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool \
|
||||
westcos-tool sc-hsm-tool dnie-tool gids-tool npa-tool
|
||||
|
@ -46,7 +48,6 @@ piv_tool_SOURCES = piv-tool.c util.c
|
|||
piv_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS)
|
||||
opensc_explorer_SOURCES = opensc-explorer.c util.c
|
||||
opensc_explorer_LDADD = $(OPTIONAL_READLINE_LIBS)
|
||||
opensc_notify_SOURCES = opensc-notify.c
|
||||
pkcs15_tool_SOURCES = pkcs15-tool.c util.c
|
||||
pkcs15_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS)
|
||||
pkcs11_tool_SOURCES = pkcs11-tool.c util.c
|
||||
|
@ -101,6 +102,30 @@ npa-tool.1:
|
|||
--source='$(PACKAGE_STRING)' \
|
||||
$(builddir)/npa-tool$(EXEEXT)
|
||||
|
||||
opensc_notify_SOURCES = opensc-notify.c $(OPENSC_NOTIFY_BUILT_SOURCES)
|
||||
opensc_notify_LDADD = $(top_builddir)/src/libopensc/libopensc.la $(OPTIONAL_NOTIFY_LIBS)
|
||||
opensc_notify_CFLAGS = -I$(top_srcdir)/src $(OPTIONAL_NOTIFY_CFLAGS)
|
||||
opensc_notify_CFLAGS += -Wno-unused-but-set-variable -Wno-unknown-warning-option
|
||||
|
||||
opensc-notify.c: $(abs_builddir)/opensc-notify.ggo $(OPENSC_NOTIFY_BUILT_SOURCES)
|
||||
|
||||
# We only want *cmdline* to be generated when they have explicitly been removed.
|
||||
$(OPENSC_NOTIFY_BUILT_SOURCES):
|
||||
$(MAKE) $(abs_builddir)/opensc-notify.ggo
|
||||
$(GENGETOPT) --include-getopt --file-name=opensc-notify-cmdline --output-dir=$(builddir) < $(abs_builddir)/opensc-notify.ggo
|
||||
|
||||
$(abs_builddir)/opensc-notify.ggo: opensc-notify.ggo.in
|
||||
$(do_subst) < $(abs_srcdir)/opensc-notify.ggo.in > $@
|
||||
|
||||
# We only want opensc-notify.1 to be generated when it has explicitly been removed.
|
||||
opensc-notify.1:
|
||||
$(MAKE) opensc-notify$(EXEEXT)
|
||||
$(HELP2MAN) \
|
||||
--output=$@ \
|
||||
--no-info \
|
||||
--source='$(PACKAGE_STRING)' \
|
||||
$(builddir)/opensc-notify$(EXEEXT)
|
||||
|
||||
if WIN32
|
||||
opensc_tool_SOURCES += versioninfo-tools.rc
|
||||
piv_tool_SOURCES += versioninfo-tools.rc
|
||||
|
@ -121,4 +146,4 @@ gids_tool_SOURCES += versioninfo-tools.rc
|
|||
endif
|
||||
|
||||
clean-local:
|
||||
rm -f $(abs_builddir)/npa-tool.ggo
|
||||
rm -f $(abs_builddir)/npa-tool.ggo $(abs_builddir)/opensc-notify.ggo
|
||||
|
|
|
@ -10,6 +10,10 @@ TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \
|
|||
$(PROGRAMS_OPENSSL)
|
||||
|
||||
OBJECTS = util.obj npa-tool-cmdline.obj fread_to_eof.obj versioninfo-tools.res
|
||||
|
||||
TARGET2 = opensc-notify.exe
|
||||
OBJECT2 = opensc-notify-cmdline.obj versioninfo-tools.res
|
||||
|
||||
LIBS = $(TOPDIR)\src\common\common.lib \
|
||||
$(TOPDIR)\src\scconf\scconf.lib \
|
||||
$(TOPDIR)\src\libopensc\opensc.lib \
|
||||
|
@ -17,11 +21,13 @@ LIBS = $(TOPDIR)\src\common\common.lib \
|
|||
$(TOPDIR)\src\common\libpkcs11.lib \
|
||||
$(TOPDIR)\src\common\libscdl.lib
|
||||
|
||||
all: $(TARGETS)
|
||||
all: $(TARGETS) $(TARGET2)
|
||||
|
||||
$(TARGETS): $(OBJECTS) $(LIBS)
|
||||
|
||||
$(TARGET2): $(OBJECT2) $(LIBS)
|
||||
|
||||
.c.exe:
|
||||
cl $(COPTS) /c $<
|
||||
link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib ws2_32.lib
|
||||
link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib shell32.lib User32.lib ws2_32.lib
|
||||
mt -manifest exe.manifest -outputresource:$@;1
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,196 @@
|
|||
/** @file opensc-notify-cmdline.h
|
||||
* @brief The header file for the command line option parser
|
||||
* generated by GNU Gengetopt version 2.22.6
|
||||
* http://www.gnu.org/software/gengetopt.
|
||||
* DO NOT modify this file, since it can be overwritten
|
||||
* @author GNU Gengetopt by Lorenzo Bettini */
|
||||
|
||||
#ifndef OPENSC_NOTIFY_CMDLINE_H
|
||||
#define OPENSC_NOTIFY_CMDLINE_H
|
||||
|
||||
/* If we use autoconf. */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for FILE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifndef CMDLINE_PARSER_PACKAGE
|
||||
/** @brief the program name (used for printing errors) */
|
||||
#define CMDLINE_PARSER_PACKAGE "opensc-notify"
|
||||
#endif
|
||||
|
||||
#ifndef CMDLINE_PARSER_PACKAGE_NAME
|
||||
/** @brief the complete program name (used for help and version) */
|
||||
#define CMDLINE_PARSER_PACKAGE_NAME "opensc-notify"
|
||||
#endif
|
||||
|
||||
#ifndef CMDLINE_PARSER_VERSION
|
||||
/** @brief the program version */
|
||||
#define CMDLINE_PARSER_VERSION VERSION
|
||||
#endif
|
||||
|
||||
/** @brief Where the command line options are stored */
|
||||
struct gengetopt_args_info
|
||||
{
|
||||
const char *help_help; /**< @brief Print help and exit help description. */
|
||||
const char *version_help; /**< @brief Print version and exit help description. */
|
||||
char * title_arg; /**< @brief Title of the notification. */
|
||||
char * title_orig; /**< @brief Title of the notification original value given at command line. */
|
||||
const char *title_help; /**< @brief Title of the notification help description. */
|
||||
char * message_arg; /**< @brief Main text of the notification. */
|
||||
char * message_orig; /**< @brief Main text of the notification original value given at command line. */
|
||||
const char *message_help; /**< @brief Main text of the notification help description. */
|
||||
int notify_card_inserted_flag; /**< @brief See notify_card_inserted in opensc.conf (default=off). */
|
||||
const char *notify_card_inserted_help; /**< @brief See notify_card_inserted in opensc.conf help description. */
|
||||
int notify_card_removed_flag; /**< @brief See notify_card_inserted in opensc.conf (default=off). */
|
||||
const char *notify_card_removed_help; /**< @brief See notify_card_inserted in opensc.conf help description. */
|
||||
int notify_pin_good_flag; /**< @brief See notify_pin_good in opensc.conf (default=off). */
|
||||
const char *notify_pin_good_help; /**< @brief See notify_pin_good in opensc.conf help description. */
|
||||
int notify_pin_bad_flag; /**< @brief See notify_pin_bad in opensc.conf (default=off). */
|
||||
const char *notify_pin_bad_help; /**< @brief See notify_pin_bad in opensc.conf help description. */
|
||||
|
||||
unsigned int help_given ; /**< @brief Whether help was given. */
|
||||
unsigned int version_given ; /**< @brief Whether version was given. */
|
||||
unsigned int title_given ; /**< @brief Whether title was given. */
|
||||
unsigned int message_given ; /**< @brief Whether message was given. */
|
||||
unsigned int notify_card_inserted_given ; /**< @brief Whether notify-card-inserted was given. */
|
||||
unsigned int notify_card_removed_given ; /**< @brief Whether notify-card-removed was given. */
|
||||
unsigned int notify_pin_good_given ; /**< @brief Whether notify-pin-good was given. */
|
||||
unsigned int notify_pin_bad_given ; /**< @brief Whether notify-pin-bad was given. */
|
||||
|
||||
int customized_mode_counter; /**< @brief Counter for mode customized */
|
||||
int daemon_mode_counter; /**< @brief Counter for mode daemon */
|
||||
int standard_mode_counter; /**< @brief Counter for mode standard */
|
||||
} ;
|
||||
|
||||
/** @brief The additional parameters to pass to parser functions */
|
||||
struct cmdline_parser_params
|
||||
{
|
||||
int override; /**< @brief whether to override possibly already present options (default 0) */
|
||||
int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */
|
||||
int check_required; /**< @brief whether to check that all required options were provided (default 1) */
|
||||
int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */
|
||||
int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */
|
||||
} ;
|
||||
|
||||
/** @brief the purpose string of the program */
|
||||
extern const char *gengetopt_args_info_purpose;
|
||||
/** @brief the usage string of the program */
|
||||
extern const char *gengetopt_args_info_usage;
|
||||
/** @brief the description string of the program */
|
||||
extern const char *gengetopt_args_info_description;
|
||||
/** @brief all the lines making the help output */
|
||||
extern const char *gengetopt_args_info_help[];
|
||||
|
||||
/**
|
||||
* The command line parser
|
||||
* @param argc the number of command line options
|
||||
* @param argv the command line options
|
||||
* @param args_info the structure where option information will be stored
|
||||
* @return 0 if everything went fine, NON 0 if an error took place
|
||||
*/
|
||||
int cmdline_parser (int argc, char **argv,
|
||||
struct gengetopt_args_info *args_info);
|
||||
|
||||
/**
|
||||
* The command line parser (version with additional parameters - deprecated)
|
||||
* @param argc the number of command line options
|
||||
* @param argv the command line options
|
||||
* @param args_info the structure where option information will be stored
|
||||
* @param override whether to override possibly already present options
|
||||
* @param initialize whether to initialize the option structure my_args_info
|
||||
* @param check_required whether to check that all required options were provided
|
||||
* @return 0 if everything went fine, NON 0 if an error took place
|
||||
* @deprecated use cmdline_parser_ext() instead
|
||||
*/
|
||||
int cmdline_parser2 (int argc, char **argv,
|
||||
struct gengetopt_args_info *args_info,
|
||||
int override, int initialize, int check_required);
|
||||
|
||||
/**
|
||||
* The command line parser (version with additional parameters)
|
||||
* @param argc the number of command line options
|
||||
* @param argv the command line options
|
||||
* @param args_info the structure where option information will be stored
|
||||
* @param params additional parameters for the parser
|
||||
* @return 0 if everything went fine, NON 0 if an error took place
|
||||
*/
|
||||
int cmdline_parser_ext (int argc, char **argv,
|
||||
struct gengetopt_args_info *args_info,
|
||||
struct cmdline_parser_params *params);
|
||||
|
||||
/**
|
||||
* Save the contents of the option struct into an already open FILE stream.
|
||||
* @param outfile the stream where to dump options
|
||||
* @param args_info the option struct to dump
|
||||
* @return 0 if everything went fine, NON 0 if an error took place
|
||||
*/
|
||||
int cmdline_parser_dump(FILE *outfile,
|
||||
struct gengetopt_args_info *args_info);
|
||||
|
||||
/**
|
||||
* Save the contents of the option struct into a (text) file.
|
||||
* This file can be read by the config file parser (if generated by gengetopt)
|
||||
* @param filename the file where to save
|
||||
* @param args_info the option struct to save
|
||||
* @return 0 if everything went fine, NON 0 if an error took place
|
||||
*/
|
||||
int cmdline_parser_file_save(const char *filename,
|
||||
struct gengetopt_args_info *args_info);
|
||||
|
||||
/**
|
||||
* Print the help
|
||||
*/
|
||||
void cmdline_parser_print_help(void);
|
||||
/**
|
||||
* Print the version
|
||||
*/
|
||||
void cmdline_parser_print_version(void);
|
||||
|
||||
/**
|
||||
* Initializes all the fields a cmdline_parser_params structure
|
||||
* to their default values
|
||||
* @param params the structure to initialize
|
||||
*/
|
||||
void cmdline_parser_params_init(struct cmdline_parser_params *params);
|
||||
|
||||
/**
|
||||
* Allocates dynamically a cmdline_parser_params structure and initializes
|
||||
* all its fields to their default values
|
||||
* @return the created and initialized cmdline_parser_params structure
|
||||
*/
|
||||
struct cmdline_parser_params *cmdline_parser_params_create(void);
|
||||
|
||||
/**
|
||||
* Initializes the passed gengetopt_args_info structure's fields
|
||||
* (also set default values for options that have a default)
|
||||
* @param args_info the structure to initialize
|
||||
*/
|
||||
void cmdline_parser_init (struct gengetopt_args_info *args_info);
|
||||
/**
|
||||
* Deallocates the string fields of the gengetopt_args_info structure
|
||||
* (but does not deallocate the structure itself)
|
||||
* @param args_info the structure to deallocate
|
||||
*/
|
||||
void cmdline_parser_free (struct gengetopt_args_info *args_info);
|
||||
|
||||
/**
|
||||
* Checks that all the required options were specified
|
||||
* @param args_info the structure to check
|
||||
* @param prog_name the name of the program that will be used to print
|
||||
* possible errors
|
||||
* @return
|
||||
*/
|
||||
int cmdline_parser_required (struct gengetopt_args_info *args_info,
|
||||
const char *prog_name);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* OPENSC_NOTIFY_CMDLINE_H */
|
|
@ -21,8 +21,24 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "libopensc/log.h"
|
||||
#include "opensc-notify-cmdline.h"
|
||||
#include "ui/notify.h"
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int run_daemon = 0;
|
||||
static struct sc_context *ctx = NULL;
|
||||
|
||||
void stop_daemon(int signo)
|
||||
{
|
||||
#ifdef PCSCLITE_GOOD
|
||||
sc_cancel(ctx);
|
||||
#endif
|
||||
run_daemon = 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <time.h>
|
||||
|
@ -41,30 +57,183 @@ void Sleep(unsigned int Milliseconds)
|
|||
|
||||
nanosleep(&req , &rem);
|
||||
}
|
||||
#else
|
||||
#include "ui/invisible_window.h"
|
||||
static HINSTANCE g_hInstance = NULL;
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (message == WM_CLOSE) {
|
||||
sc_cancel(ctx);
|
||||
run_daemon = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
#endif
|
||||
|
||||
void notify_daemon(void)
|
||||
{
|
||||
int r;
|
||||
const unsigned int event_mask = SC_EVENT_CARD_EVENTS;
|
||||
unsigned int event;
|
||||
struct sc_reader *event_reader = NULL;
|
||||
size_t error_count = 0;
|
||||
/* timeout adjusted to the maximum response time for WM_CLOSE in case
|
||||
* canceling doesn't work */
|
||||
const int timeout = 20000;
|
||||
struct sc_atr old_atr;
|
||||
void *reader_states = NULL;
|
||||
#ifdef _WIN32
|
||||
LPCTSTR lpszClassName = "OPENSC_NOTIFY_CLASS";
|
||||
HWND hwnd = create_invisible_window(lpszClassName, WndProc, g_hInstance);
|
||||
#elif HAVE_SIGACTION
|
||||
struct sigaction new_sig, old_sig;
|
||||
|
||||
/* Register signal handlers */
|
||||
new_sig.sa_handler = stop_daemon;
|
||||
sigemptyset(&new_sig.sa_mask);
|
||||
new_sig.sa_flags = SA_RESTART;
|
||||
if ((sigaction(SIGINT, &new_sig, &old_sig) < 0)
|
||||
|| (sigaction(SIGTERM, &new_sig, &old_sig) < 0)) {
|
||||
fprintf(stderr, "Failed to create signal handler: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
r = sc_establish_context(&ctx, "opensc-notify");
|
||||
if (r < 0 || !ctx) {
|
||||
fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r));
|
||||
return;
|
||||
}
|
||||
|
||||
while (run_daemon) {
|
||||
if (0 > sc_wait_for_event(ctx, event_mask, &event_reader,
|
||||
&event, timeout, &reader_states)) {
|
||||
error_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
error_count = 0;
|
||||
|
||||
if (event & SC_EVENT_CARD_REMOVED) {
|
||||
sc_notify_id(ctx, &old_atr, NULL, NOTIFY_CARD_REMOVED);
|
||||
}
|
||||
if (event & SC_EVENT_CARD_INSERTED) {
|
||||
if (event_reader) {
|
||||
/* FIXME `pcsc_wait_for_event` has all the information that's
|
||||
* requested again with `pcsc_detect_card_presence`, but it
|
||||
* doesn't use the ATR, for example, to refresh the reader's
|
||||
* attributes. To get the ATR we need to call
|
||||
* sc_detect_card_presence. Eventually this should be fixed. */
|
||||
sc_detect_card_presence(event_reader);
|
||||
memcpy(old_atr.value, event_reader->atr.value,
|
||||
event_reader->atr.len);
|
||||
old_atr.len = event_reader->atr.len;
|
||||
} else {
|
||||
old_atr.len = 0;
|
||||
}
|
||||
sc_notify_id(ctx, old_atr.len ? &old_atr : NULL, NULL,
|
||||
NOTIFY_CARD_INSERTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx) {
|
||||
/* free `reader_states` */
|
||||
sc_wait_for_event(ctx, 0, NULL, NULL, 0, &reader_states);
|
||||
reader_states = NULL;
|
||||
sc_release_context(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
delete_invisible_window(hwnd, lpszClassName, g_hInstance);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "ui/char_str_from_wchar.h"
|
||||
#include <shellapi.h>
|
||||
|
||||
/* This application shall be executable without a console. Therefor we're
|
||||
* creating a windows application that requires `WinMain()` rather than
|
||||
* `main()` as entry point. As benefit, we can properly handle `WM_CLOSE`. */
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
LPWSTR *wargv = NULL;
|
||||
char **argv = NULL;
|
||||
int argc = 0, i;
|
||||
struct gengetopt_args_info cmdline;
|
||||
|
||||
wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
if (wargv == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
argv = LocalAlloc(0, (sizeof *argv) * argc);
|
||||
if (argv == NULL) {
|
||||
goto err;
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv[i] = char_str_from_wchar(wargv[i]);
|
||||
}
|
||||
|
||||
g_hInstance = hInstance;
|
||||
|
||||
#else
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const char *title = NULL, *text = NULL;
|
||||
switch (argc) {
|
||||
case 3:
|
||||
text = argv[2];
|
||||
/* fall through */
|
||||
case 2:
|
||||
title = argv[1];
|
||||
/* fall through */
|
||||
case 1:
|
||||
break;
|
||||
struct gengetopt_args_info cmdline;
|
||||
#endif
|
||||
|
||||
if (cmdline_parser(argc, argv, &cmdline) != 0)
|
||||
goto err;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Usage: opensc-notify [title [text]]");
|
||||
return 1;
|
||||
}
|
||||
sc_notify_init();
|
||||
sc_notify(title, text);
|
||||
Sleep(250);
|
||||
|
||||
if (cmdline.customized_mode_counter) {
|
||||
sc_notify(cmdline.title_arg, cmdline.message_arg);
|
||||
}
|
||||
|
||||
if (cmdline.standard_mode_counter) {
|
||||
if (cmdline.notify_card_inserted_flag) {
|
||||
sc_notify_id(NULL, NULL, NULL, NOTIFY_CARD_INSERTED);
|
||||
}
|
||||
if (cmdline.notify_card_removed_flag) {
|
||||
sc_notify_id(NULL, NULL, NULL, NOTIFY_CARD_REMOVED);
|
||||
}
|
||||
if (cmdline.notify_pin_good_flag) {
|
||||
sc_notify_id(NULL, NULL, NULL, NOTIFY_PIN_GOOD);
|
||||
}
|
||||
if (cmdline.notify_pin_bad_flag) {
|
||||
sc_notify_id(NULL, NULL, NULL, NOTIFY_PIN_BAD);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!cmdline.customized_mode_counter && !cmdline.standard_mode_counter)
|
||||
|| cmdline.daemon_mode_counter) {
|
||||
run_daemon = 1;
|
||||
notify_daemon();
|
||||
} else {
|
||||
/* give the notification process some time to spawn */
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
sc_notify_close();
|
||||
|
||||
cmdline_parser_free (&cmdline);
|
||||
err:
|
||||
#ifdef _WIN32
|
||||
if (argv) {
|
||||
for (i = 0; i <= argc; i++) {
|
||||
LocalFree(argv[i]);
|
||||
}
|
||||
LocalFree(argv);
|
||||
}
|
||||
LocalFree(wargv);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package "opensc-notify"
|
||||
purpose "@PACKAGE_SUMMARY@"
|
||||
description "If no arguments are given, monitor smart card events and send the appropriate notification."
|
||||
|
||||
defmode "daemon"
|
||||
modedesc="Monitor smart card events to send notifications."
|
||||
defmode "standard"
|
||||
modedesc="Manually send standard notifications."
|
||||
defmode "customized"
|
||||
modedesc="Send customized notifications."
|
||||
|
||||
modeoption "title" t
|
||||
"Title of the notification"
|
||||
string
|
||||
mode="customized"
|
||||
argoptional
|
||||
optional
|
||||
modeoption "message" m
|
||||
"Main text of the notification"
|
||||
string
|
||||
mode="customized"
|
||||
argoptional
|
||||
optional
|
||||
|
||||
modeoption "notify-card-inserted" I
|
||||
"See notify_card_inserted in opensc.conf"
|
||||
flag off
|
||||
mode="standard"
|
||||
modeoption "notify-card-removed" R
|
||||
"See notify_card_inserted in opensc.conf"
|
||||
flag off
|
||||
mode="standard"
|
||||
modeoption "notify-pin-good" G
|
||||
"See notify_pin_good in opensc.conf"
|
||||
flag off
|
||||
mode="standard"
|
||||
modeoption "notify-pin-bad" B
|
||||
"See notify_pin_bad in opensc.conf"
|
||||
flag off
|
||||
mode="standard"
|
||||
|
||||
text "
|
||||
Report bugs to @PACKAGE_BUGREPORT@
|
||||
|
||||
Written by Frank Morgner <frankmorgner@gmail.com>"
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* char_str_from_wchar.h: Conversion from wide string to string
|
||||
*
|
||||
* Copyright (C) 2017 Frank Morgner <frankmorgner@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static char *char_str_from_wchar(const WCHAR *in)
|
||||
{
|
||||
char *out;
|
||||
int out_len;
|
||||
|
||||
if (!in)
|
||||
return NULL;
|
||||
|
||||
out_len = WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, NULL, NULL);
|
||||
if (0 >= out_len)
|
||||
return NULL;
|
||||
|
||||
out = LocalAlloc(0, (sizeof *out) * out_len);
|
||||
if (!out)
|
||||
return NULL;
|
||||
|
||||
out_len = WideCharToMultiByte(CP_UTF8, 0, in, -1, out, out_len, NULL, NULL);
|
||||
if (out_len == 0xFFFD || 0 >= out_len) {
|
||||
LocalFree(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* invisible_window.h: Create invisible Window
|
||||
*
|
||||
* Copyright (C) 2017 Frank Morgner <frankmorgner@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HWND create_invisible_window(LPCTSTR lpszClassName,
|
||||
LRESULT (CALLBACK* WndProc)(HWND, UINT, WPARAM, LPARAM),
|
||||
HINSTANCE hInstance)
|
||||
{
|
||||
HWND hWnd = NULL;
|
||||
WNDCLASSEX wx = {0};
|
||||
|
||||
//Register Window class
|
||||
wx.cbSize = sizeof(WNDCLASSEX);
|
||||
wx.lpfnWndProc = WndProc;
|
||||
wx.hInstance = hInstance;
|
||||
wx.lpszClassName = lpszClassName;
|
||||
if (RegisterClassEx(&wx)) {
|
||||
/* create window */
|
||||
hWnd = CreateWindowEx(0, lpszClassName, lpszClassName, 0, 0, 0, 0, 0,
|
||||
HWND_MESSAGE, NULL, NULL, NULL );
|
||||
}
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
static BOOL delete_invisible_window(HWND hWnd, LPCTSTR lpszClassName,
|
||||
HINSTANCE hInstance)
|
||||
{
|
||||
BOOL r;
|
||||
r = DestroyWindow(hWnd);
|
||||
r &= UnregisterClass(lpszClassName, hInstance);
|
||||
|
||||
return r;
|
||||
}
|
102
src/ui/notify.c
102
src/ui/notify.c
|
@ -65,6 +65,7 @@ void sc_notify_close(void)
|
|||
|
||||
#if defined(ENABLE_NOTIFY) && defined(_WIN32)
|
||||
|
||||
#include "invisible_window.h"
|
||||
#include "wchar_from_char_str.h"
|
||||
#include <shellapi.h>
|
||||
|
||||
|
@ -72,13 +73,14 @@ static const GUID myGUID = {0x23977b55, 0x10e0, 0x4041, {0xb8,
|
|||
0x62, 0xb1, 0x95, 0x41, 0x96, 0x36, 0x69}};
|
||||
HINSTANCE sc_notify_instance = NULL;
|
||||
HWND hwndNotification = NULL;
|
||||
BOOL delete_icon = TRUE;
|
||||
#define IDI_SMARTCARD 102
|
||||
#define IDI_UNLOCKED 103
|
||||
#define IDI_LOCKED 104
|
||||
#define IDI_READER_EMPTY 105
|
||||
#define IDI_CARD_INSERTED 106
|
||||
UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1;
|
||||
BOOL RestoreTooltip(void);
|
||||
static BOOL RestoreTooltip();
|
||||
|
||||
// we need commctrl v6 for LoadIconMetric()
|
||||
#include <commctrl.h>
|
||||
|
@ -100,54 +102,16 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
static const char* class_name = "DUMMY_CLASS";
|
||||
static const char* window_name = "DUMMY_WINDOW";
|
||||
|
||||
static BOOL create_invisible_window(void)
|
||||
{
|
||||
if (!hwndNotification) {
|
||||
//Register Window class
|
||||
WNDCLASSEX wx = {0};
|
||||
wx.cbSize = sizeof(WNDCLASSEX);
|
||||
wx.lpfnWndProc = WndProc; // function which will handle messages
|
||||
wx.hInstance = sc_notify_instance;
|
||||
wx.lpszClassName = class_name;
|
||||
if (!RegisterClassEx(&wx)) {
|
||||
return FALSE;
|
||||
}
|
||||
/* create window */
|
||||
hwndNotification = CreateWindowEx(0, class_name, window_name,
|
||||
0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
|
||||
}
|
||||
|
||||
if (hwndNotification) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL delete_invisible_window(void)
|
||||
{
|
||||
BOOL r;
|
||||
r = DestroyWindow(hwndNotification);
|
||||
r &= UnregisterClass(class_name, sc_notify_instance);
|
||||
|
||||
hwndNotification = NULL;
|
||||
|
||||
return r;
|
||||
}
|
||||
static const char* lpszClassName = "NOTIFY_CLASS";
|
||||
|
||||
static BOOL AddNotificationIcon(void)
|
||||
{
|
||||
NOTIFYICONDATA nid = {sizeof(nid)};
|
||||
NOTIFYICONDATA nid;
|
||||
TCHAR path[MAX_PATH]={0};
|
||||
BOOL r;
|
||||
|
||||
if (!create_invisible_window()) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&nid, 0, sizeof nid);
|
||||
nid.cbSize = sizeof nid;
|
||||
nid.hWnd = hwndNotification;
|
||||
// add the icon, setting the icon, tooltip, and callback message.
|
||||
// the icon will be identified with the GUID
|
||||
|
@ -156,7 +120,18 @@ static BOOL AddNotificationIcon(void)
|
|||
nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK;
|
||||
LoadIconMetric(sc_notify_instance, MAKEINTRESOURCEW(IDI_SMARTCARD), LIM_SMALL, &nid.hIcon);
|
||||
if (GetModuleFileName(NULL, path, ARRAYSIZE(path))) {
|
||||
strcpy_s(nid.szTip, ARRAYSIZE(nid.szTip), path);
|
||||
const char *basename = strrchr(path, '\\');
|
||||
if (basename) {
|
||||
basename++;
|
||||
if (0 != strcmp(basename, "opensc-notify.exe")) {
|
||||
/* Allow creation of sytem tray icon only for
|
||||
* "opensc-notify.exe" to avoid creation of the same icon by
|
||||
* multiple processes. */
|
||||
delete_icon = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
strlcpy(nid.szTip, path, ARRAYSIZE(nid.szTip));
|
||||
} else {
|
||||
strcpy(nid.szTip, PACKAGE_NAME);
|
||||
}
|
||||
|
@ -166,19 +141,32 @@ static BOOL AddNotificationIcon(void)
|
|||
nid.uVersion = NOTIFYICON_VERSION_4;
|
||||
r &= Shell_NotifyIcon(NIM_SETVERSION, &nid);
|
||||
|
||||
hwndNotification = create_invisible_window(lpszClassName, WndProc, sc_notify_instance);
|
||||
if (!hwndNotification) {
|
||||
r = FALSE;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static BOOL DeleteNotificationIcon(void)
|
||||
{
|
||||
BOOL r;
|
||||
NOTIFYICONDATA nid = {sizeof(nid)};
|
||||
NOTIFYICONDATA nid;
|
||||
|
||||
if (!delete_icon) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&nid, 0, sizeof nid);
|
||||
nid.cbSize = sizeof nid;
|
||||
nid.uFlags = NIF_GUID;
|
||||
nid.guidItem = myGUID;
|
||||
|
||||
r = Shell_NotifyIcon(NIM_DELETE, &nid);
|
||||
r &= delete_invisible_window();
|
||||
|
||||
r &= delete_invisible_window(hwndNotification, lpszClassName,
|
||||
sc_notify_instance);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -186,8 +174,10 @@ static BOOL DeleteNotificationIcon(void)
|
|||
static BOOL RestoreTooltip()
|
||||
{
|
||||
// After the balloon is dismissed, restore the tooltip.
|
||||
NOTIFYICONDATA nid = {sizeof(nid)};
|
||||
NOTIFYICONDATA nid;
|
||||
|
||||
memset(&nid, 0, sizeof nid);
|
||||
nid.cbSize = sizeof nid;
|
||||
nid.uFlags = NIF_SHOWTIP | NIF_GUID;
|
||||
nid.guidItem = myGUID;
|
||||
|
||||
|
@ -197,17 +187,19 @@ static BOOL RestoreTooltip()
|
|||
static void notify_shell(struct sc_context *ctx,
|
||||
const char *title, const char *text, WORD icon)
|
||||
{
|
||||
NOTIFYICONDATA nid = {sizeof(nid)};
|
||||
NOTIFYICONDATA nid;
|
||||
|
||||
memset(&nid, 0, sizeof nid);
|
||||
nid.cbSize = sizeof nid;
|
||||
nid.uFlags = NIF_GUID;
|
||||
nid.guidItem = myGUID;
|
||||
|
||||
if (title) {
|
||||
strcpy_s(nid.szInfoTitle, ARRAYSIZE(nid.szInfoTitle), title);
|
||||
strlcpy(nid.szInfoTitle, title, ARRAYSIZE(nid.szInfoTitle));
|
||||
}
|
||||
if (text) {
|
||||
nid.uFlags |= NIF_INFO;
|
||||
strcpy_s(nid.szInfo, ARRAYSIZE(nid.szInfo), text);
|
||||
strlcpy(nid.szInfo, text, ARRAYSIZE(nid.szInfo));
|
||||
}
|
||||
if (icon) {
|
||||
nid.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON;
|
||||
|
@ -240,17 +232,11 @@ void sc_notify(const char *title, const char *text)
|
|||
void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr,
|
||||
struct sc_pkcs15_card *p15card, enum ui_str id)
|
||||
{
|
||||
const char *title, *text, *group;
|
||||
const char *title, *text;
|
||||
WORD icon;
|
||||
title = ui_get_str(ctx, atr, p15card, id);
|
||||
text = ui_get_str(ctx, atr, p15card, id+1);
|
||||
|
||||
if (p15card && p15card->card && p15card->card->reader) {
|
||||
group = p15card->card->reader->name;
|
||||
} else {
|
||||
group = ctx ? ctx->app_name : NULL;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case NOTIFY_CARD_INSERTED:
|
||||
icon = IDI_CARD_INSERTED;
|
||||
|
@ -533,7 +519,7 @@ void sc_notify_id(struct sc_context *ctx, struct sc_atr *atr,
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_NOTIFY) && (defined(ENABLE_GIO2) || defined(GDBUS))
|
||||
#if defined(ENABLE_NOTIFY) && (defined(ENABLE_GIO2) || defined(GDBUS) && !defined(_WIN32))
|
||||
void sc_notify(const char *title, const char *text)
|
||||
{
|
||||
notify_gio(NULL, title, text, NULL, NULL);
|
||||
|
|
|
@ -138,6 +138,9 @@
|
|||
<Component Id="opensc_tool.exe" Guid="*" Win64="$(var.Win64YesNo)">
|
||||
<File Source="$(var.SOURCE_DIR)\src\tools\opensc-tool.exe" Vital="yes"/>
|
||||
</Component>
|
||||
<Component Id="opensc_notify.exe" Guid="*" Win64="$(var.Win64YesNo)">
|
||||
<File Source="$(var.SOURCE_DIR)\src\tools\opensc-notify.exe" Vital="yes"/>
|
||||
</Component>
|
||||
<Component Id="pkcs11_tool.exe" Guid="*" Win64="$(var.Win64YesNo)">
|
||||
<File Source="$(var.SOURCE_DIR)\src\tools\pkcs11-tool.exe" Vital="yes"/>
|
||||
</Component>
|
||||
|
@ -340,6 +343,7 @@
|
|||
<Feature Id="OpenSC_tools" Level="1" Title="Tools and profiles" Description="Tools for debugging and personalization. Includes profiles needed for running pkcs15-init.exe">
|
||||
<ComponentRef Id="opensc_explorer.exe"/>
|
||||
<ComponentRef Id="opensc_tool.exe"/>
|
||||
<ComponentRef Id="opensc_notify.exe"/>
|
||||
<ComponentRef Id="pkcs11_tool.exe"/>
|
||||
<ComponentRef Id="cardos_tool.exe"/>
|
||||
<ComponentRef Id="eidenv.exe"/>
|
||||
|
|
Loading…
Reference in New Issue