diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 299675f..0000000 --- a/.clang-format +++ /dev/null @@ -1,8 +0,0 @@ -BasedOnStyle: Google -IndentWidth: 4 -InsertBraces: true -ColumnLimit: 79 -AlignConsecutiveMacros: Consecutive -AllowShortFunctionsOnASingleLine: None -AllowShortLoopsOnASingleLine: false -AllowShortIfStatementsOnASingleLine: Never diff --git a/.clang-tidy b/.clang-tidy deleted file mode 100644 index 17ce268..0000000 --- a/.clang-tidy +++ /dev/null @@ -1,30 +0,0 @@ -Checks: | - -*, - abseil-*, - bugprone-*, - clang-analyzer-*, - misc-*, - modernize-*, - performance-*, - portability-*, - readability-*, - llvm-*, - -bugprone-easily-swappable-parameters, - -readability-avoid-const-params-in-decls, - -readability-identifier-length - -CheckOptions: - - key: readability-inconsistent-declaration-parameter-name.Strict - value: true - - key: readability-identifier-naming.StructCase - value: lower_case - - key: readability-identifier-naming.FunctionCase - value: lower_case - - key: readability-identifier-naming.VariableCase - value: lower_case - - key: readability-identifier-naming.EnumConstantCase - value: UPPER_CASE - - key: readability-identifier-naming.MacroDefinitionCase - value: UPPER_CASE - - key: readability-function-cognitive-complexity.Threshold - value: 15 diff --git a/.clangd b/.clangd deleted file mode 100644 index f8cd025..0000000 --- a/.clangd +++ /dev/null @@ -1,3 +0,0 @@ -Diagnostics: - UnusedIncludes: Strict - MissingIncludes: Strict diff --git a/.gitignore b/.gitignore index fe2faa5..14ebea9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ build *.o pinentry-dmenu -compile_commands.json diff --git a/Makefile b/Makefile index bbef800..a7b1df4 100644 --- a/Makefile +++ b/Makefile @@ -1,66 +1,68 @@ # pinentry-dmenu - dmenu-like stupid pin entry # See LICENSE file for copyright and license details. +.POSIX: include config.mk SRC = pinentry-dmenu.c drw.c util.c -OBJ = ${SRC:.c=.o} -OBJ_PIN = pinentry/pinentry.o pinentry/util.o pinentry/password-cache.o pinentry/argparse.o pinentry/secmem.o +OBJ = $(SRC:.c=.o) +PIN_SRC = \ + pinentry/argparse.c\ + pinentry/password-cache.c\ + pinentry/pinentry.c\ + pinentry/secmem.c\ + pinentry/util.c +PIN_OBJ = $(PIN_SRC:.c=.o) +PIN_DEP = \ + pinentry/argparse.h\ + pinentry/password-cache.h\ + pinentry/pinentry.h\ + pinentry/memory.h\ + pinentry/util.h all: options pinentry-dmenu options: @echo pinentry-dmenu build options: - @echo "CFLAGS = ${CFLAGS}" - @echo "LDFLAGS = ${LDFLAGS}" - @echo "CC = ${CC}" + @echo "CFLAGS = $(CFLAGS)" + @echo "LDFLAGS = $(LDFLAGS)" + @echo "CC = $(CC)" .c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< + $(CC) -c $(CFLAGS) $(INCS) $(CPPFLAGS) -o $@ -c $< config.h: - @echo creating $@ from config.def.h - @cp config.def.h $@ + cp config.def.h $@ -${OBJ}: config.h config.mk drw.h +$(OBJ): config.h config.mk drw.h -pinentry: - $(MAKE) -C pinentry +$(PIN_OBJ): $(PIN_DEP) -pinentry-dmenu: pinentry pinentry-dmenu.o drw.o util.o - @echo CC -o $@ - @${CC} -o $@ ${OBJ} ${OBJ_PIN} ${LDFLAGS} -lassuan -lgpgme -lgpg-error -lconfig +pinentry-dmenu: $(OBJ) $(PIN_OBJ) + $(CC) -o $@ $(OBJ) $(PIN_OBJ) $(LDFLAGS) $(LIBS) clean: - @echo cleaning - @rm -f pinentry-dmenu ${OBJ} - $(MAKE) -C pinentry/ clean + rm -f pinentry-dmenu $(OBJ) $(PIN_OBJ) dist: clean - @echo creating dist tarball - @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1 \ - drw.h util.h dmenu_path dmenu_run stest.1 ${SRC} \ - dmenu-${VERSION} - @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} - @gzip dmenu-${VERSION}.tar - @rm -rf dmenu-${VERSION} + mkdir -p pinentry-dmenu-$(VERSION) + cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1 \ + drw.h util.h $(SRC) \ + pinentry-dmenu-$(VERSION) + tar -cf pinentry-dmenu-$(VERSION).tar pinentry-dmenu-$(VERSION) + gzip pinentry-dmenu-$(VERSION).tar + rm -rf pinentry-dmenu-$(VERSION) install: all - @echo installing executable to ${DESTDIR}${PREFIX}/bin - @mkdir -p ${DESTDIR}${PREFIX}/bin - @cp -f pinentry-dmenu ${DESTDIR}${PREFIX}/bin - @chmod 755 ${DESTDIR}${PREFIX}/bin/pinentry-dmenu - @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1 - @mkdir -p ${DESTDIR}${MANPREFIX}/man1 - @sed "s/VERSION/${VERSION}/g;s/DATE/${DATE}/g;s/BUGREPORT/${BUGREPORT}/g" < pinentry-dmenu.1 > ${DESTDIR}${MANPREFIX}/man1/pinentry-dmenu.1 - @chmod 644 ${DESTDIR}${MANPREFIX}/man1/pinentry-dmenu.1 + mkdir -p $(DESTDIR)$(PREFIX)/bin + cp -f pinentry-dmenu $(DESTDIR)$(PREFIX)/bin + chmod 755 $(DESTDIR)$(PREFIX)/bin/pinentry-dmenu + mkdir -p $(DESTDIR)$(MANPREFIX)/man1 + sed "s/VERSION/$(VERSION)/g" < pinentry-dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/pinentry-dmenu.1 + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/pinentry-dmenu.1 uninstall: - @echo removing executable from ${DESTDIR}${PREFIX}/bin - @rm -f ${DESTDIR}${PREFIX}/bin/pinentry-dmenu - @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 - @rm -f ${DESTDIR}${MANPREFIX}/man1/pinentry-dmenu.1 + rm -f $(DESTDIR)$(PREFIX)/bin/pinentry-dmenu + rm -f $(DESTDIR)$(MANPREFIX)/man1/pinentry-dmenu.1 .PHONY: all options clean dist install pinentry uninstall diff --git a/README.md b/README.md index 0800d8c..c92d72f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ pinentry-dmenu is a pinentry program with the charm of [dmenu](https://tools.suc This program is a fork from [spine](https://gitgud.io/zavok/spine.git) which is also a fork from [dmenu](https://tools.suckless.org/dmenu). +This is a further fork of pinentry-dmenu with many of the upstream [dmenu](https://tools.suckless.org/dmenu) changes merged and config file support removed. + Requirements ------------ @@ -25,41 +27,4 @@ Config ------ To use pinentry-dmenu add in `~/.gnupg/gpg-agent.conf`: - pinentry-program - -The config is located in `~/.gnupg/pinentry-dmenu.conf`. - -Parameter | Default | Description -:------------------ |:----------------- |:----------- -asterisk | * | Defines the symbol which is showed for each typed character -bottom | false | pinentry-dmenu appears at the bottom of the screen -min_password_length | 32 | The minimal space of the password field. This value has affect to the description field after the password field -monitor | -1 | pinentry-dmenu is displayed on the monitor number supplied. Monitor numbers are starting from 0 -prompt | "" | Defines the prompt to be displayed to the left of the input field -font | monospace:size=10 | Defines the font or font set used -prompt_bg | #bbbbbb | Defines the prompt background color -prompt_fg | #222222 | Defines the prompt foreground color -normal_bg | #bbbbbb | Defines the normal background color -normal_fg | #222222 | Defines the normal foreground color -select_bg | #eeeeee | Defines the selected background color -select_fg | #005577 | Defines the selected foreground color -desc_bg | #bbbbbb | Defines the description background color -desc_fg | #222222 | Defines the description foreground color -embedded | false | Embed into window - - -Example -------- -``` -asterisk= "# "; -prompt = "$"; -font = "Noto Sans UI:size=13"; -prompt_fg = "#eeeeee"; -prompt_bg = "#d9904a"; -normal_fg = "#ffffff"; -normal_bg = "#000000"; -select_fg = "#eeeeee"; -select_bg = "#d9904a"; -desc_fg = "#eeeeee"; -desc_bg = "#d9904a"; -``` + pinentry-program diff --git a/config.def.h b/config.def.h new file mode 100644 index 0000000..49de006 --- /dev/null +++ b/config.def.h @@ -0,0 +1,24 @@ +/* See LICENSE file for copyright and license details. */ + +/* minimum length to use for displaying the pw field */ +static int minpwflen = 16; + +/* character to be used as a replacement for typed characters */ +static const char *asterisk = "*"; + +/* if 0, pinentry-dmenu appears at bottom */ +static int topbar = 1; + +/* default X11 font or font set */ +static const char *fonts[] = { + "monospace:size=10" +}; + +static const char *prompt = NULL; +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemePrompt] = { "#bbbbbb", "#222222" }, + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, + [SchemeDesc] = { "#bbbbbb", "#222222" } +}; diff --git a/config.h b/config.h index 8b016f5..1ebaecb 100644 --- a/config.h +++ b/config.h @@ -1,14 +1,6 @@ -/* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ - -static int bottom = 0; -static int embedded = 0; -static int minpwlen = 32; -static int mon = -1; -static int lineheight = 0; -static int min_lineheight = 8; - +static int minpwflen = 16; static const char *asterisk = ""; +static int topbar = 1; static const char *fonts[] = { "FiraCode Nerd Font Mono:pixelsize=14", "Noto Color Emoji:pixelsize=14", @@ -19,4 +11,5 @@ static const char *colors[SchemeLast][4] = { [SchemePrompt] = {"#7aa2f7", "#15161E"}, [SchemeNormal] = {"#7aa2f7", "#15161E"}, [SchemeSelect] = {"#15161E", "#7aa2f7"}, - [SchemeDesc] = {"#7aa2f7", "#15161E"}}; + [SchemeDesc] = {"#7aa2f7", "#15161E"} +}; diff --git a/config.mk b/config.mk index 4c71211..fe4b2ca 100644 --- a/config.mk +++ b/config.mk @@ -1,11 +1,10 @@ # Pinentry settings -DATE = $$(date +'%B %Y') VERSION = 0.1 -BUGREPORT = https:\/\/github.com\/ritze\/pinentry-dmenu +BUGREPORT = https:\/\/github.com\/0x766F6964\/pinentry-dmenu # Paths PREFIX = /usr/local -MANPREFIX = ${PREFIX}/share/man +MANPREFIX = $(PREFIX)/share/man X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib @@ -18,16 +17,16 @@ XINERAMAFLAGS = -DXINERAMA FREETYPELIBS = -lfontconfig -lXft FREETYPEINC = /usr/include/freetype2 # OpenBSD (uncomment) -#FREETYPEINC = ${X11INC}/freetype2 +#FREETYPEINC = $(X11INC)/freetype2 # Includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} +INCS = -I$(X11INC) -I$(FREETYPEINC) +LIBS = -lassuan -lgpg-error -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) # Flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -DPACKAGE_VERSION=\"${VERSION}\" -DPACKAGE_BUGREPORT=\"${BUGREPORT}\" -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} -LDFLAGS = -s ${LIBS} +CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) -DPACKAGE_VERSION=\"$(VERSION)\" -DPACKAGE_BUGREPORT=\"$(BUGREPORT)\" -DHAVE_MLOCK +CFLAGS = -std=c99 -pedantic -Wall -Os +LDFLAGS = -s # Compiler and linker CC = cc diff --git a/drw.c b/drw.c index c1582e7..78a2b27 100644 --- a/drw.c +++ b/drw.c @@ -95,6 +95,7 @@ drw_free(Drw *drw) { XFreePixmap(drw->dpy, drw->drawable); XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); free(drw); } @@ -237,12 +238,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) { - char buf[1024]; - int ty; - unsigned int ew; + int ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1; XftDraw *d = NULL; Fnt *usedfont, *curfont, *nextfont; - size_t i, len; int utf8strlen, utf8charlen, render = x || y || w || h; long utf8codepoint = 0; const char *utf8str; @@ -250,13 +249,15 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp FcPattern *fcpattern; FcPattern *match; XftResult result; - int charexists = 0; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + static unsigned int nomatches[128], ellipsis_width; - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) return 0; if (!render) { - w = ~w; + w = invert ? invert : ~invert; } else { XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); @@ -268,8 +269,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); while (1) { - utf8strlen = 0; + ew = ellipsis_len = utf8strlen = 0; utf8str = text; nextfont = NULL; while (*text) { @@ -277,9 +280,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp for (curfont = drw->fonts; curfont; curfont = curfont->next) { charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); if (charexists) { - if (curfont == usedfont) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { utf8strlen += utf8charlen; text += utf8charlen; + ew += tmpw; } else { nextfont = curfont; } @@ -287,36 +308,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp } } - if (!charexists || nextfont) + if (overflow || !charexists || nextfont) break; else charexists = 0; } if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - - if (len) { - memcpy(buf, utf8str, len); - buf[len] = '\0'; - if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)buf, len); - } - x += ew; - w -= ew; + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); } + x += ew; + w -= ew; } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); - if (!*text) { + if (!*text || overflow) { break; } else if (nextfont) { charexists = 0; @@ -326,6 +336,15 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp * character must be drawn. */ charexists = 1; + hash = (unsigned int)utf8codepoint; + hash = ((hash >> 16) ^ hash) * 0x21F0AAAD; + hash = ((hash >> 15) ^ hash) * 0xD35A2D97; + h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches); + h1 = (hash >> 17) % LENGTH(nomatches); + /* avoid expensive XftFontMatch call when we know we won't find a match */ + if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint) + goto no_match; + fccharset = FcCharSetCreate(); FcCharSetAddChar(fccharset, utf8codepoint); @@ -353,6 +372,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp curfont->next = usedfont; } else { xfont_free(usedfont); + nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint; +no_match: usedfont = drw->fonts; } } @@ -382,6 +403,15 @@ drw_fontset_getwidth(Drw *drw, const char *text) return drw_text(drw, 0, 0, 0, 0, 0, text, 0); } +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) { diff --git a/drw.h b/drw.h index 4c67419..fd7631b 100644 --- a/drw.h +++ b/drw.h @@ -35,6 +35,7 @@ void drw_free(Drw *drw); Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); void drw_fontset_free(Fnt* set); unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); /* Colorscheme abstraction */ diff --git a/pinentry-dmenu.1 b/pinentry-dmenu.1 index a6775ed..1c374e2 100644 --- a/pinentry-dmenu.1 +++ b/pinentry-dmenu.1 @@ -1,4 +1,4 @@ -.TH PINENTRY-DMENU 1 "DATE" pinentry-dmenu\-VERSION "pinentry-dmenu Manual" +.TH PINENTRY-DMENU 1 pinentry-dmenu\-VERSION "pinentry-dmenu Manual" .SH NAME @@ -19,63 +19,6 @@ to .B pinentry-dmenu to use the program as the regular dialog for .BR gpg-agent . -.PP -The configuration is placed in -.IR ~/.gnupg/pinentry-dmenu.conf . -You can change the path to the config file with the environment variable -.IR GNUPGHOME . - - -.SH OPTIONS -.TP -.BI "asterisk =" " *" -Defines the symbol which is showed for each typed character. -.TP -.BI "bottom =" " false" -pinentry-dmenu appears at the bottom of the screen. -.TP -.BI "min_password_length =" " 32" -The minimal space of the password field. This value has affect to the description field after the password field. -.TP -.BI "monitor =" " -1" -pinentry-dmenu is displayed on the monitor number supplied. Monitor numbers are starting from 0. -.TP -.BI "prompt =" " """" -Defines the prompt to be displayed to the left of the input field. -.TP -.BI "font =" " monospace:size=10" -Defines the font or font set used. -.TP -.BI "prompt_bg =" " #bbbbbb" -Defines the prompt background color. -.IR #RGB , -.I #RRGGBB -and X color names are supported. -.TP -.BI "prompt_fg =" " #222222" -Defines the prompt foreground color. -.TP -.BI "normal_bg =" " #bbbbbb" -Defines the normal background color. -.TP -.BI "normal_fg =" " #222222" -Defines the normal foreground color. -.TP -.BI "select_bg =" " #eeeeee" -Defines the selected background color. -.TP -.BI "select_fg =" " #005577" -Defines the selected foreground color. -.TP -.BI "desc_bg =" " #bbbbbb" -Defines the description background color. -.TP -.BI "desc_fg =" " #222222" -Defines the description foreground color. -.TP -.BI "embedded =" " false" -Embed into window. - .SH USAGE pinentry-dmenu is completely controlled by the keyboard. @@ -184,25 +127,6 @@ Delete line left Paste from primary X selection -.SH EXAMPLES -.sp -.if n \{ -.RS 4 -.\} -.nf -asterisk= "# "; -prompt = "$"; -font = "Noto Sans UI:size=13"; -prompt_fg = "#eeeeee"; -prompt_bg = "#d9904a"; -normal_fg = "#ffffff"; -normal_bg = "#000000"; -select_fg = "#eeeeee"; -select_bg = "#d9904a"; -desc_fg = "#eeeeee"; -desc_bg = "#d9904a"; - - .SH AUTHORS .B pinentry-dmenu is a fork of @@ -214,11 +138,6 @@ and uses the api of .B pinentry-dmenu itself was written by Moritz Lüdecke . - -.SH REPORTING BUGS -Report pinentry-dmenu bugs to - - .SH SEE ALSO .BR dmenu (1), .BR dwm (1), diff --git a/pinentry-dmenu.c b/pinentry-dmenu.c index 453a350..d26b0a4 100644 --- a/pinentry-dmenu.c +++ b/pinentry-dmenu.c @@ -1,6 +1,5 @@ /* See LICENSE file for copyright and license details. */ #include -#include #include #include #include @@ -25,32 +24,28 @@ #include "pinentry/pinentry.h" #include "pinentry/memory.h" -#define CONFIG_DIR "/.gnupg" -#define CONFIG_FILE "/pinentry-dmenu.conf" -#define INTERSECT(x, y, w, h, r) \ - (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ - && MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) -#define LENGTH(X) (sizeof(X) / sizeof(X[0])) +#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ + * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) #define MINDESCLEN 8 - -enum { SchemePrompt, SchemeNormal, SchemeSelect, SchemeDesc, SchemeLast }; +/* enums */ +enum { SchemePrompt, SchemeNormal, SchemeSelect, SchemeDesc, SchemeLast }; /* color schemes */ enum { WinPin, WinConfirm }; -enum { Ok, NotOk, Cancel }; enum { Nothing, Yes, No }; +/* FIXME: this can't currently be set */ +static char *embed; static int bh, mw, mh; static int sel; static int promptw, pdescw; -/* Sum of left and right padding */ -static int lrpad; +static int lrpad; /* sum of left and right padding */ static size_t cursor; -static int screen; +static int mon = -1, screen; -static char* pin; +static char *pin; static int pin_len; -static char* pin_repeat; +static char *pin_repeat; static int pin_repeat_len; static int repeat; @@ -69,7 +64,8 @@ pinentry_t pinentry_info; #include "config.h" static int -drawitem(const char* text, Bool sel, int x, int y, int w) { +drawitem(const char* text, Bool sel, int x, int y, int w) +{ unsigned int i = (sel) ? SchemeSelect : SchemeNormal; drw_setscheme(drw, scheme[i]); @@ -78,57 +74,54 @@ drawitem(const char* text, Bool sel, int x, int y, int w) { } static void -grabfocus(void) { +grabfocus(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; Window focuswin; int i, revertwin; for (i = 0; i < 100; ++i) { XGetInputFocus(dpy, &focuswin, &revertwin); - if (focuswin == win) { + if (focuswin == win) return; - } XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - usleep(1000); + nanosleep(&ts, NULL); } - die("cannot grab focus"); } static void -grabkeyboard(void) { +grabkeyboard(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; int i; - if (embedded) { + if (embed) return; - } - - /* Try to grab keyboard, - * we may have to wait for another process to ungrab */ + /* try to grab keyboard, we may have to wait for another process to ungrab */ for (i = 0; i < 1000; i++) { if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) { + GrabModeAsync, CurrentTime) == GrabSuccess) return; - } - usleep(1000); + nanosleep(&ts, NULL); } - die("cannot grab keyboard"); } static size_t -nextrune(int cursor, int inc) { +nextrune(int inc) +{ ssize_t n; - /* Return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = cursor + inc; - n + inc >= 0 && (pin[n] & 0xc0) == 0x80; - n += inc); - + /* return location of next utf8 rune in the given direction (+1 or -1) */ + for (n = cursor + inc; n + inc >= 0 && (pin[n] & 0xc0) == 0x80; n += inc) + ; return n; } static void -setup_pin(char* pin_ptr, int len, int reset) { +setup_pin(char *pin_ptr, int len, int reset) +{ pin = pin_ptr; pin_len = len; @@ -136,14 +129,14 @@ setup_pin(char* pin_ptr, int len, int reset) { promptw = (prompt) ? TEXTW(prompt) - lrpad / 4 : 0; cursor = 0; - if (pin) { + if (pin) pin[0] = '\0'; - } } } static void -insert(const char *str, ssize_t n) { +insert(const char *str, ssize_t n) +{ size_t len = strlen(pin); // FIXME: Pinentry crashes when increasing the pin buffer the second time. @@ -153,15 +146,13 @@ insert(const char *str, ssize_t n) { pin_repeat_len = 2 * pin_repeat_len; pin_repeat = secmem_realloc(pin_repeat, pin_repeat_len); setup_pin(pin_repeat, pin_repeat_len, 0); - if (!pin_repeat) { + if (!pin_repeat) pin_len = 0; - } } else { - if (!pinentry_setbufferlen(pinentry_info, 2 * pinentry_info->pin_len)) { + if (!pinentry_setbufferlen(pinentry_info, 2 * pinentry_info->pin_len)) pin_len = 0; - } else { + else setup_pin(pinentry_info->pin, pinentry_info->pin_len, 0); - } } if (pin_len == 0) { printf("Error: Couldn't allocate secure memory\n"); @@ -169,27 +160,27 @@ insert(const char *str, ssize_t n) { } } - /* Move existing text out of the way, insert new text, and update cursor */ + /* move existing text out of the way, insert new text, and update cursor */ memmove(&pin[cursor + n], &pin[cursor], pin_len - cursor - MAX(n, 0)); - if (n > 0) { + if (n > 0) memcpy(&pin[cursor], str, n); - } cursor += n; pin[len + n] = '\0'; } static void -drawwin(void) { +drawmenu(void) +{ unsigned int curpos; - int x = 0, pb, pbw = 0, i; + int x = 0, fh = drw->fonts->h, pb, pbw = 0, i; size_t asterlen = strlen(asterisk); size_t pdesclen; int leftinput; - char* censort; + char *censort; - char* pprompt = (repeat) ? pinentry_info->repeat_passphrase : pinentry_info->prompt; + char *pprompt = (repeat) ? pinentry_info->repeat_passphrase : pinentry_info->prompt; int ppromptw = (pprompt) ? TEXTW(pprompt) : 0; unsigned int censortl = minpwlen * TEXTW(asterisk) / strlen(asterisk); @@ -223,11 +214,9 @@ drawwin(void) { pbw = MIN(pbw, pb); pb = mw - pbw; - for (i = 0; i < pdesclen; i++) { - if (pinentry_info->description[i] == '\n') { + for (i = 0; i < pdesclen; i++) + if (pinentry_info->description[i] == '\n') pinentry_info->description[i] = ' '; - } - } drw_setscheme(drw, scheme[SchemeDesc]); drw_text(drw, pb, 0, pbw, bh, lrpad / 2, pinentry_info->description, @@ -244,18 +233,17 @@ drawwin(void) { if (winmode == WinPin) { censort = ecalloc(1, asterlen * pin_len); - for (i = 0; i < asterlen * strlen(pin); i += asterlen) { + for (i = 0; i < asterlen * strlen(pin); i += asterlen) memcpy(&censort[i], asterisk, asterlen); - } censort[i+1] = '\n'; leftinput = mw - x - pbw; drw_text(drw, x, 0, leftinput, bh, lrpad / 2, censort, 0); - drw_font_getexts(drw->fonts, censort, cursor * asterlen, &curpos, NULL); + curpos = TEXTW(censort) - TEXTW(&censort[cursor]); if ((curpos += lrpad / 2 - 1) < leftinput) { drw_setscheme(drw, scheme[SchemeNormal]); - drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); + drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0); } free(censort); @@ -264,29 +252,27 @@ drawwin(void) { x = drawitem("No", (sel == No), x, 0, TEXTW("No")); x = drawitem("Yes", (sel == Yes), x, 0, TEXTW("Yes")); } - drw_map(drw, win, 0, 0, mw, mh); } static void -setup(void) { - int x, y, i = 0; +setup(void) +{ + int x, y, i, j; unsigned int du; XSetWindowAttributes swa; XIM xim; Window w, dw, *dws; XWindowAttributes wa; + XClassHint ch = {"pinentry-dmenu", "pinentry-dmenu"}; #ifdef XINERAMA XineramaScreenInfo *info; Window pw; - int a, j, di, n, area = 0; + int a, di, n, area = 0; #endif - - /* Init appearance */ - scheme[SchemePrompt] = drw_scm_create(drw, colors[SchemePrompt], 2); - scheme[SchemeNormal] = drw_scm_create(drw, colors[SchemeNormal], 2); - scheme[SchemeSelect] = drw_scm_create(drw, colors[SchemeSelect], 2); - scheme[SchemeDesc] = drw_scm_create(drw, colors[SchemeDesc], 2); + /* init appearance */ + for (j = 0; j < SchemeLast; j++) + scheme[j] = drw_scm_create(drw, colors[j], 2); clip = XInternAtom(dpy, "CLIPBOARD", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False); @@ -295,52 +281,43 @@ setup(void) { bh = drw->fonts->h + 2; mh = bh; #ifdef XINERAMA - info = XineramaQueryScreens(dpy, &n); - - if (parentwin == root && info) { + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); - if (mon >= 0 && mon < n) { + if (mon >= 0 && mon < n) i = mon; - } else if (w != root && w != PointerRoot && w != None) { - /* Find top-level window containing current input focus */ + else if (w != root && w != PointerRoot && w != None) { + /* find top-level window containing current input focus */ do { - if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) { + if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) XFree(dws); - } } while (w != root && w != pw); - /* Find xinerama screen with which the window intersects most */ - if (XGetWindowAttributes(dpy, pw, &wa)) { - for (j = 0; j < n; j++) { - a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j]); - if (a > area) { + /* find xinerama screen with which the window intersects most */ + if (XGetWindowAttributes(dpy, pw, &wa)) + for (j = 0; j < n; j++) + if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { area = a; i = j; } - } - } } - /* No focused window is on screen, so use pointer location instead */ - if (mon < 0 && !area - && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) { - for (i = 0; i < n; i++) { - if (INTERSECT(x, y, 1, 1, info[i])) { + /* no focused window is on screen, so use pointer location instead */ + if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + for (i = 0; i < n; i++) + if (INTERSECT(x, y, 1, 1, info[i]) != 0) break; - } - } - } x = info[i].x_org; - y = info[i].y_org + (bottom ? info[i].height - mh : 0); + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; XFree(info); } else #endif { - if (!XGetWindowAttributes(dpy, parentwin, &wa)) { - die("could not get embedding window attributes: 0x%lx", parentwin); - } + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); x = 0; - y = bottom ? wa.height - mh : 0; + y = topbar ? 0 : wa.height - mh; mw = wa.width; } @@ -353,43 +330,44 @@ setup(void) { win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + XSetClassHint(dpy, win, &ch); + + /* input methods */ + if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) + die("XOpenIM failed: could not open input device"); - /* Open input methods */ - xim = XOpenIM(dpy, NULL, NULL, NULL); xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dpy, win); - - if (embedded) { - XSelectInput(dpy, parentwin, FocusChangeMask); + if (embed) { + XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { - for (i = 0; i < du && dws[i] != win; ++i) { + for (i = 0; i < du && dws[i] != win; ++i) XSelectInput(dpy, dws[i], FocusChangeMask); - } - XFree(dws); } grabfocus(); } - drw_resize(drw, mw, mh); } static void -cleanup(void) { +cleanup(void) +{ + size_t i; + XUngrabKey(dpy, AnyKey, AnyModifier, root); - free(scheme[SchemeDesc]); - free(scheme[SchemeSelect]); - free(scheme[SchemeNormal]); - free(scheme[SchemePrompt]); + for (i = 0; i < SchemeLast; i++) + free(scheme[i]); drw_free(drw); XSync(dpy, False); XCloseDisplay(dpy); } static int -keypress_confirm(XKeyEvent *ev, KeySym ksym) { +keypress_confirm(XKeyEvent *ev, KeySym ksym) +{ if (ev->state & ControlMask) { switch(ksym) { case XK_c: @@ -404,9 +382,8 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) { switch(ksym) { case XK_KP_Enter: case XK_Return: - if (sel != Nothing) { + if (sel != Nothing) return 1; - } break; case XK_y: case XK_Y: @@ -425,17 +402,23 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) { case XK_h: case XK_j: case XK_Home: + case XK_KP_Home: case XK_Left: + case XK_KP_Left: case XK_Prior: + case XK_KP_Prior: case XK_Up: + case XK_KP_Up: sel = No; break; case XK_k: case XK_l: case XK_Down: + case XK_KP_Down: case XK_End: case XK_Next: case XK_Right: + case XK_KP_Right: sel = Yes; break; } @@ -444,7 +427,8 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) { } static int -keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) { +keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) +{ int old; if (ev->state & ControlMask) { @@ -482,34 +466,35 @@ keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) { switch(ksym) { case XK_Delete: - if (pin[cursor] == '\0') { + case XK_KP_Delete: + if (pin[cursor] == '\0') return 0; - } - cursor = nextrune(cursor, +1); + cursor = nextrune(+1); /* Fallthrough */ case XK_BackSpace: - if (cursor == 0) { + if (cursor == 0) return 0; - } - insert(NULL, nextrune(cursor, -1) - cursor); + insert(NULL, nextrune(-1) - cursor); break; case XK_Escape: pinentry_info->canceled = 1; return 1; case XK_Left: - if (cursor > 0) { - cursor = nextrune(cursor, -1); - } + case XK_KP_Left: + if (cursor > 0) + cursor = nextrune(-1); break; case XK_Right: - if (pin[cursor] != '\0') { - cursor = nextrune(cursor, +1); - } + case XK_KP_Right: + if (pin[cursor] != '\0') + cursor = nextrune(+1); break; case XK_Home: + case XK_KP_Home: cursor = 0; break; case XK_End: + case XK_KP_End: cursor = strlen(pin); break; case XK_Return: @@ -517,16 +502,16 @@ keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) { return 1; break; default: - if (!iscntrl(*buf)) { + if (!iscntrl((unsigned char)*buf)) insert(buf, len); - } } return 0; } static int -keypress(XKeyEvent *ev) { +keypress(XKeyEvent *ev) +{ char buf[32]; int len; int ret = 1; @@ -536,79 +521,83 @@ keypress(XKeyEvent *ev) { len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status); if (status != XBufferOverflow) { - if (winmode == WinConfirm) { + if (winmode == WinConfirm) ret = keypress_confirm(ev, ksym); - } else { + else ret = keypress_pin(ev, ksym, buf, len); - } - if (ret == 0) { - drawwin(); - } + if (ret == 0) + drawmenu(); } return ret; } static void -paste(void) { +paste(void) +{ char *p, *q; int di; unsigned long dl; Atom da; - /* We have been given the current selection, now insert it into input */ - XGetWindowProperty(dpy, win, utf8, 0, pin_len / 4, False, utf8, &da, &di, - &dl, &dl, (unsigned char **)&p); - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t) strlen(p)); - XFree(p); - drawwin(); + /* we have been given the current selection, now insert it into input */ + if (XGetWindowProperty(dpy, win, utf8, 0, (pin_len/ 4) + 1, False, + utf8, &da, &di, &dl, &dl, (unsigned char **)&p) + == Success && p) { + insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); + XFree(p); + } + drawmenu(); } void -run(void) { +run(void) +{ XEvent ev; - drawwin(); + drawmenu(); while (!XNextEvent(dpy, &ev)) { - if (XFilterEvent(&ev, win)) { + if (XFilterEvent(&ev, win)) continue; - } switch(ev.type) { + case DestroyNotify: + if (ev.xdestroywindow.window != win) + break; + cleanup(); + exit(1); case Expose: - if (ev.xexpose.count == 0) { + if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); - } break; case KeyPress: - if (keypress(&ev.xkey)) { + if (keypress(&ev.xkey)) return; - } break; case SelectionNotify: - if (ev.xselection.property == utf8) { + if (ev.xselection.property == utf8) paste(); - } break; case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) { + if (ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); - } break; } } } +/* FIXME: this does nothing */ static void -catchsig(int sig) { - if (sig == SIGALRM) { +catchsig(int sig) +{ + if (sig == SIGALRM) timed_out = 1; - } } static void -password(void) { +password(void) +{ winmode = WinPin; repeat = 0; setup_pin(pinentry_info->pin, pinentry_info->pin_len, 1); @@ -639,7 +628,8 @@ password(void) { } static void -confirm(void) { +confirm(void) +{ winmode = WinConfirm; sel = Nothing; run(); @@ -647,30 +637,33 @@ confirm(void) { } static int -cmdhandler(pinentry_t received_pinentry) { +cmdhandler(pinentry_t received_pinentry) +{ struct sigaction sa; XWindowAttributes wa; pinentry_info = received_pinentry; - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) { + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); - } - if (!(dpy = XOpenDisplay(pinentry_info->display))) { + if (!(dpy = XOpenDisplay(pinentry_info->display))) die("cannot open display"); - } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - embedded = (pinentry_info->parent_wid) ? embedded : 0; - parentwin = (embedded) ? pinentry_info->parent_wid : root; - if (!XGetWindowAttributes(dpy, parentwin, &wa)) { + embed = (pinentry_info->parent_wid) ? embed : 0; + parentwin = (embed) ? pinentry_info->parent_wid : root; + if (!XGetWindowAttributes(dpy, parentwin, &wa)) die("could not get embedding window attributes: 0x%lx", parentwin); - } drw = drw_create(dpy, screen, root, wa.width, wa.height); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) { + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); - } lrpad = drw->fonts->h; + +#ifdef __OpenBSD__ + if (pledge("stdio rpath", NULL) == -1) + die("pledge"); +#endif + drw_setscheme(drw, scheme[SchemePrompt]); if (pinentry_info->timeout) { @@ -683,14 +676,13 @@ cmdhandler(pinentry_t received_pinentry) { grabkeyboard(); setup(); - if (pinentry_info->pin) { + if (pinentry_info->pin) do { password(); } while (!pinentry_info->canceled && pinentry_info->repeat_passphrase - && !pinentry_info->repeat_okay); - } else { + && !pinentry_info->repeat_okay); + else confirm(); - } cleanup(); @@ -700,100 +692,13 @@ cmdhandler(pinentry_t received_pinentry) { pinentry_cmd_handler_t pinentry_cmd_handler = cmdhandler; int -main(int argc, char *argv[]) { - Bool bval; - int i, val; - const char *str; - struct passwd *pw; - char path[PATH_MAX]; - char *sudo_uid = getenv("SUDO_UID"); - char *home = getenv("HOME"); - char *gnupghome = getenv("GNUPGHOME"); - config_t cfg; - - if (gnupghome) { - i = strlen(gnupghome); - strcpy(path, gnupghome); - } else { - /* Get the home dir even if the user used sudo or logged in as root */ - if (sudo_uid) { - i = atoi(sudo_uid); - pw = getpwuid(i); - home = pw->pw_dir; - } - - i = strlen(home); - strcpy(path, home); - strcpy(&path[i], CONFIG_DIR); - i += strlen(CONFIG_DIR); - } - - strcpy(&path[i], CONFIG_FILE); - endpwent(); - - config_init(&cfg); - - /* Read the file. If there is an error, report it and exit. */ - if (config_read_file(&cfg, path)) { - if (config_lookup_string(&cfg, "asterisk", &str)) { - asterisk = str; - } - if (config_lookup_bool(&cfg, "bottom", &bval)) { - bottom = bval; - } - if (config_lookup_int(&cfg, "min_password_length", &val)) { - minpwlen = val; - } - if (config_lookup_int(&cfg, "monitor", &val)) { - mon = val; - } - if (config_lookup_string(&cfg, "prompt", &str)) { - prompt = str; - } - if (config_lookup_string(&cfg, "font", &str)) { - fonts[0] = str; - } - if (config_lookup_string(&cfg, "prompt_bg", &str)) { - colors[SchemePrompt][ColBg] = str; - } - if (config_lookup_string(&cfg, "prompt_fg", &str)) { - colors[SchemePrompt][ColFg] = str; - } - if (config_lookup_string(&cfg, "normal_bg", &str)) { - colors[SchemeNormal][ColBg] = str; - } - if (config_lookup_string(&cfg, "normal_fg", &str)) { - colors[SchemeNormal][ColFg] = str; - } - if (config_lookup_string(&cfg, "select_bg", &str)) { - colors[SchemeSelect][ColBg] = str; - } - if (config_lookup_string(&cfg, "select_fg", &str)) { - colors[SchemeSelect][ColFg] = str; - } - if (config_lookup_string(&cfg, "desc_bg", &str)) { - colors[SchemeDesc][ColBg] = str; - } - if (config_lookup_string(&cfg, "desc_fg", &str)) { - colors[SchemeDesc][ColFg] = str; - } - if (config_lookup_bool(&cfg, "embedded", &bval)) { - embedded = bval; - } - } else if ((str = config_error_file(&cfg))) { - fprintf(stderr, "%s:%d: %s\n", config_error_file(&cfg), - config_error_line(&cfg), config_error_text(&cfg)); - return(EXIT_FAILURE); - } - +main(int argc, char *argv[]) +{ pinentry_init("pinentry-dmenu"); pinentry_parse_opts(argc, argv); - if (pinentry_loop()) { + if (pinentry_loop()) return 1; - } - - config_destroy(&cfg); return 0; } diff --git a/pinentry/Makefile b/pinentry/Makefile deleted file mode 100644 index 4de2470..0000000 --- a/pinentry/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -include ../config.mk - -SRC = util.c pinentry.c argparse.c password-cache.c secmem.c -OBJ = ${SRC:.c=.o} -CFLAGS += -DHAVE_MLOCK - -all: pinentry - -.c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< - -${OBJ}: pinentry.h argparse.h password-cache.h memory.h util.h - -pinentry: pinentry.o argparse.o password-cache.o secmem.o util.o - -clean: - @echo cleaning - @rm -f ${OBJ} - -.PHONY: all clean pinentry diff --git a/pinentry/secmem++.h b/pinentry/secmem++.h deleted file mode 100644 index 88a5d45..0000000 --- a/pinentry/secmem++.h +++ /dev/null @@ -1,91 +0,0 @@ -/* STL allocator for secmem - * Copyright (C) 2008 Marc Mutz - * - * 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 2 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, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __SECMEM_SECMEMPP_H__ -#define __SECMEM_SECMEMPP_H__ - -#include "secmem/memory.h" -#include - -namespace secmem { - - template - class alloc { - public: - // type definitions: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - // rebind - template - struct rebind { - typedef alloc other; - }; - - // address - pointer address( reference value ) const { - return &value; - } - const_pointer address( const_reference value ) const { - return &value; - } - - // (trivial) ctors and dtors - alloc() {} - alloc( const alloc & ) {} - template alloc( const alloc & ) {} - // copy ctor is ok - ~alloc() {} - - // de/allocation - size_type max_size() const { - return secmem_get_max_size(); - } - - pointer allocate( size_type n, void * =0 ) { - return static_cast( secmem_malloc( n * sizeof(T) ) ); - } - - void deallocate( pointer p, size_type ) { - secmem_free( p ); - } - - // de/construct - void construct( pointer p, const T & value ) { - void * loc = p; - new (loc)T(value); - } - void destruct( pointer p ) { - p->~T(); - } - }; - - // equality comparison - template - bool operator==( const alloc &, const alloc & ) { return true; } - template - bool operator!=( const alloc &, const alloc & ) { return false; } - -} - -#endif /* __SECMEM_SECMEMPP_H__ */ diff --git a/test b/test index c63c8ce..bfe07d5 100755 --- a/test +++ b/test @@ -1,6 +1,6 @@ #!/bin/sh -if [[ $1 -eq 1 ]]; then +if [ $1 -eq 1 ]; then echo "SETTITLE title SETPROMPT prompt @@ -8,7 +8,7 @@ SETDESC PROMPT GETPIN BYE" | ./pinentry-dmenu -elif [[ $1 -eq 2 ]]; then +elif [ $1 -eq 2 ]; then echo "SETTITLE title SETPROMPT confirm @@ -16,7 +16,7 @@ SETDESC CONFIRM confirm BYE" | ./pinentry-dmenu -elif [[ $1 -eq 3 ]]; then +elif [ $1 -eq 3 ]; then echo "SETTITLE title SETPROMPT prompt diff --git a/util.c b/util.c index fe044fc..96b82c9 100644 --- a/util.c +++ b/util.c @@ -6,18 +6,9 @@ #include "util.h" -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; - - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; -} - void -die(const char *fmt, ...) { +die(const char *fmt, ...) +{ va_list ap; va_start(ap, fmt); @@ -33,3 +24,13 @@ die(const char *fmt, ...) { exit(1); } + +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; +} diff --git a/util.h b/util.h index f633b51..c0a50d4 100644 --- a/util.h +++ b/util.h @@ -3,6 +3,7 @@ #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B)) #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) +#define LENGTH(X) (sizeof (X) / sizeof (X)[0]) void die(const char *fmt, ...); void *ecalloc(size_t nmemb, size_t size);