commit - 6f0a03b88dab13c5b9dbb264ad6087abda50c90a
commit + dc349050d70345b448ae4d359cb20f634919a2a4
blob - 186e69be0ae503732e3a9db3d3456a3041bd5276
blob + 343ef4bad293ee4c2924bd3d989327cfe3bc6cf2
--- Makefile
+++ Makefile
SRC_SLOCK = slock/slock.c
HDR_SLOCK = slock/arg.h slock/config.h slock/util.h
-SRC_PD = pinentry-dmenu/pinentry-dmenu.c \
- pinentry-dmenu/drw.c \
- pinentry-dmenu/util.c \
- pinentry-dmenu/pinentry/pinentry.c \
- pinentry-dmenu/pinentry/util.c \
- pinentry-dmenu/pinentry/password-cache.c \
- pinentry-dmenu/pinentry/argparse.c \
- pinentry-dmenu/pinentry/secmem.c
-HDR_PD = master.h \
- pinentry-dmenu/config.h \
- pinentry-dmenu/drw.h \
- pinentry-dmenu/util.h \
- pinentry-dmenu/pinentry/argparse.h \
- pinentry-dmenu/pinentry/memory.h \
- pinentry-dmenu/pinentry/util.h \
- pinentry-dmenu/pinentry/password-cache.h \
- pinentry-dmenu/pinentry/secmem-util.h \
- pinentry-dmenu/pinentry/pinentry.h
-
SRC_PD2 = pinentry-dmenu2.sh
-MAN = dwm/dwm.1 st/st.1 dmenu/dmenu.1 dmenu/stest.1 slock/slock.1 pinentry-dmenu/pinentry-dmenu.1
+MAN = dwm/dwm.1 st/st.1 dmenu/dmenu.1 dmenu/stest.1 slock/slock.1
-all: bin/dwm bin/st bin/bedstatus bin/dmenu bin/stest bin/xbgcd bin/slock bin/pinentry-dmenu bin/pinentry-dmenu2
+all: bin/dwm bin/st bin/bedstatus bin/dmenu bin/stest bin/xbgcd bin/slock bin/pinentry-dmenu2
check:
find etc/common etc/$$(uname) -not -type d | awk '{a=$$0; sub(/etc\/[^\/]+/, "/etc", a); system("diff -u " $$0 " " a)}'
@mkdir -p bin
${CC} -o $@ ${SRC_SLOCK} ${CFLAGS} `pkg-config --cflags --libs x11 xext xrandr` -lpthread
-bin/pinentry-dmenu: ${SRC_PD} ${HDR_PD}
- @mkdir -p bin
- ${CC} -o $@ ${SRC_PD} ${CFLAGS} `pkg-config --cflags --libs libassuan gpg-error fontconfig freetype2 x11 xft xinerama`
-
bin/pinentry-dmenu2: ${SRC_PD2}
@mkdir -p bin
cp -f ${SRC_PD2} $@
blob - c7aea1896f776a9dea105ff388d6058a612d4961 (mode 644)
blob + /dev/null
--- pinentry-dmenu/LICENSE
+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
blob - f9e400ea366d163a64889d0807e1c0dd0f4d7c47 (mode 644)
blob + /dev/null
--- pinentry-dmenu/config.h
+++ /dev/null
-/* See LICENSE file for copyright and license details. */
-/* Default settings; can be overriden by command line. */
-
-#include "../master.h"
-
-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 const char *asterisk = "*";
-static const char *fonts[] = {
- TOPBAR_FONT
-};
-static const char *prompt = NULL;
-static const char *colors[SchemeLast][4] = {
- [SchemePrompt] = { "#bbbbbb", "#222222" },
- [SchemeNormal] = { "#bbbbbb", "#222222" },
- [SchemeSelect] = { "#eeeeee", "#005577" },
- [SchemeDesc] = { "#bbbbbb", "#222222" }
-};
blob - c1582e746cc57b7a475c1de3fcc53507cdb50b37 (mode 644)
blob + /dev/null
--- pinentry-dmenu/drw.c
+++ /dev/null
-/* See LICENSE file for copyright and license details. */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#define UTF_INVALID 0xFFFD
-#define UTF_SIZ 4
-
-static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
-static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
-static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
-static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-
-static long
-utf8decodebyte(const char c, size_t *i)
-{
- for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
- if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
- return (unsigned char)c & ~utfmask[*i];
- return 0;
-}
-
-static size_t
-utf8validate(long *u, size_t i)
-{
- if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
- *u = UTF_INVALID;
- for (i = 1; *u > utfmax[i]; ++i)
- ;
- return i;
-}
-
-static size_t
-utf8decode(const char *c, long *u, size_t clen)
-{
- size_t i, j, len, type;
- long udecoded;
-
- *u = UTF_INVALID;
- if (!clen)
- return 0;
- udecoded = utf8decodebyte(c[0], &len);
- if (!BETWEEN(len, 1, UTF_SIZ))
- return 1;
- for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
- udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
- if (type)
- return j;
- }
- if (j < len)
- return 0;
- *u = udecoded;
- utf8validate(u, len);
-
- return len;
-}
-
-Drw *
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
-{
- Drw *drw = ecalloc(1, sizeof(Drw));
-
- drw->dpy = dpy;
- drw->screen = screen;
- drw->root = root;
- drw->w = w;
- drw->h = h;
- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
- drw->gc = XCreateGC(dpy, root, 0, NULL);
- XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
-
- return drw;
-}
-
-void
-drw_resize(Drw *drw, unsigned int w, unsigned int h)
-{
- if (!drw)
- return;
-
- drw->w = w;
- drw->h = h;
- if (drw->drawable)
- XFreePixmap(drw->dpy, drw->drawable);
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
-}
-
-void
-drw_free(Drw *drw)
-{
- XFreePixmap(drw->dpy, drw->drawable);
- XFreeGC(drw->dpy, drw->gc);
- free(drw);
-}
-
-/* This function is an implementation detail. Library users should use
- * drw_fontset_create instead.
- */
-static Fnt *
-xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
-{
- Fnt *font;
- XftFont *xfont = NULL;
- FcPattern *pattern = NULL;
-
- if (fontname) {
- /* Using the pattern found at font->xfont->pattern does not yield the
- * same substitution results as using the pattern returned by
- * FcNameParse; using the latter results in the desired fallback
- * behaviour whereas the former just results in missing-character
- * rectangles being drawn, at least with some fonts. */
- if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
- fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
- return NULL;
- }
- if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
- fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
- XftFontClose(drw->dpy, xfont);
- return NULL;
- }
- } else if (fontpattern) {
- if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
- fprintf(stderr, "error, cannot load font from pattern.\n");
- return NULL;
- }
- } else {
- die("no font specified.");
- }
-
- font = ecalloc(1, sizeof(Fnt));
- font->xfont = xfont;
- font->pattern = pattern;
- font->h = xfont->ascent + xfont->descent;
- font->dpy = drw->dpy;
-
- return font;
-}
-
-static void
-xfont_free(Fnt *font)
-{
- if (!font)
- return;
- if (font->pattern)
- FcPatternDestroy(font->pattern);
- XftFontClose(font->dpy, font->xfont);
- free(font);
-}
-
-Fnt*
-drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
-{
- Fnt *cur, *ret = NULL;
- size_t i;
-
- if (!drw || !fonts)
- return NULL;
-
- for (i = 1; i <= fontcount; i++) {
- if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
- cur->next = ret;
- ret = cur;
- }
- }
- return (drw->fonts = ret);
-}
-
-void
-drw_fontset_free(Fnt *font)
-{
- if (font) {
- drw_fontset_free(font->next);
- xfont_free(font);
- }
-}
-
-void
-drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
-{
- if (!drw || !dest || !clrname)
- return;
-
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen),
- clrname, dest))
- die("error, cannot allocate color '%s'", clrname);
-}
-
-/* Wrapper to create color schemes. The caller has to call free(3) on the
- * returned color scheme when done using it. */
-Clr *
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
-{
- size_t i;
- Clr *ret;
-
- /* need at least two colors for a scheme */
- if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
- return NULL;
-
- for (i = 0; i < clrcount; i++)
- drw_clr_create(drw, &ret[i], clrnames[i]);
- return ret;
-}
-
-void
-drw_setfontset(Drw *drw, Fnt *set)
-{
- if (drw)
- drw->fonts = set;
-}
-
-void
-drw_setscheme(Drw *drw, Clr *scm)
-{
- if (drw)
- drw->scheme = scm;
-}
-
-void
-drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
-{
- if (!drw || !drw->scheme)
- return;
- XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
- if (filled)
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- else
- XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
-}
-
-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;
- 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;
- FcCharSet *fccharset;
- FcPattern *fcpattern;
- FcPattern *match;
- XftResult result;
- int charexists = 0;
-
- if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
- return 0;
-
- if (!render) {
- w = ~w;
- } else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
- x += lpad;
- w -= lpad;
- }
-
- usedfont = drw->fonts;
- while (1) {
- utf8strlen = 0;
- utf8str = text;
- nextfont = NULL;
- while (*text) {
- utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
- for (curfont = drw->fonts; curfont; curfont = curfont->next) {
- charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
- if (charexists) {
- if (curfont == usedfont) {
- utf8strlen += utf8charlen;
- text += utf8charlen;
- } else {
- nextfont = curfont;
- }
- break;
- }
- }
-
- if (!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 (!*text) {
- break;
- } else if (nextfont) {
- charexists = 0;
- usedfont = nextfont;
- } else {
- /* Regardless of whether or not a fallback font is found, the
- * character must be drawn. */
- charexists = 1;
-
- fccharset = FcCharSetCreate();
- FcCharSetAddChar(fccharset, utf8codepoint);
-
- if (!drw->fonts->pattern) {
- /* Refer to the comment in xfont_create for more information. */
- die("the first font in the cache must be loaded from a font string.");
- }
-
- fcpattern = FcPatternDuplicate(drw->fonts->pattern);
- FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
- FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
-
- FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
- FcDefaultSubstitute(fcpattern);
- match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
-
- FcCharSetDestroy(fccharset);
- FcPatternDestroy(fcpattern);
-
- if (match) {
- usedfont = xfont_create(drw, NULL, match);
- if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
- for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
- ; /* NOP */
- curfont->next = usedfont;
- } else {
- xfont_free(usedfont);
- usedfont = drw->fonts;
- }
- }
- }
- }
- if (d)
- XftDrawDestroy(d);
-
- return x + (render ? w : 0);
-}
-
-void
-drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
-{
- if (!drw)
- return;
-
- XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
- XSync(drw->dpy, False);
-}
-
-unsigned int
-drw_fontset_getwidth(Drw *drw, const char *text)
-{
- if (!drw || !drw->fonts || !text)
- return 0;
- return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
-}
-
-void
-drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
-{
- XGlyphInfo ext;
-
- if (!font || !text)
- return;
-
- XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
- if (w)
- *w = ext.xOff;
- if (h)
- *h = font->h;
-}
-
-Cur *
-drw_cur_create(Drw *drw, int shape)
-{
- Cur *cur;
-
- if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
- return NULL;
-
- cur->cursor = XCreateFontCursor(drw->dpy, shape);
-
- return cur;
-}
-
-void
-drw_cur_free(Drw *drw, Cur *cursor)
-{
- if (!cursor)
- return;
-
- XFreeCursor(drw->dpy, cursor->cursor);
- free(cursor);
-}
blob - 4c67419a98dd6d87e0b15e6f14094f24aa44c143 (mode 644)
blob + /dev/null
--- pinentry-dmenu/drw.h
+++ /dev/null
-/* See LICENSE file for copyright and license details. */
-
-typedef struct {
- Cursor cursor;
-} Cur;
-
-typedef struct Fnt {
- Display *dpy;
- unsigned int h;
- XftFont *xfont;
- FcPattern *pattern;
- struct Fnt *next;
-} Fnt;
-
-enum { ColFg, ColBg }; /* Clr scheme index */
-typedef XftColor Clr;
-
-typedef struct {
- unsigned int w, h;
- Display *dpy;
- int screen;
- Window root;
- Drawable drawable;
- GC gc;
- Clr *scheme;
- Fnt *fonts;
-} Drw;
-
-/* Drawable abstraction */
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
-void drw_resize(Drw *drw, unsigned int w, unsigned int h);
-void drw_free(Drw *drw);
-
-/* Fnt abstraction */
-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);
-void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
-
-/* Colorscheme abstraction */
-void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
-
-/* Cursor abstraction */
-Cur *drw_cur_create(Drw *drw, int shape);
-void drw_cur_free(Drw *drw, Cur *cursor);
-
-/* Drawing context manipulation */
-void drw_setfontset(Drw *drw, Fnt *set);
-void drw_setscheme(Drw *drw, Clr *scm);
-
-/* Drawing functions */
-void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
-int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
-
-/* Map functions */
-void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
blob - 695d0bae2fc394836118e15ec86ca097bdbe9ceb (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/AUTHORS
+++ /dev/null
-Program: Pinentry
-Bug reports: <gpa-dev@gnupg.org>
-Security related bug reports: <security@gnupg.org>
-License: GPLv2+
-
-Robert Bihlmeyer <robbe@orcus.priv.at>
-Werner Koch, g10 Code GmbH <wk@gnupg.org>
-Steffen Hansen, Klarälvdalens Datakonsult AB <steffen@klaralvdalens-datakonsult.se>
-Marcus Brinkmann, g10 Code GmbH <marcus@g10code.com>
-Timo Schulz, g10 Code GmbH
-Neal Walfied, g10 Code GmbH <neal@gnu.org>
blob - c7aea1896f776a9dea105ff388d6058a612d4961 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/COPYING
+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
blob - 4de24703f540b239f128d04550337e58d769936b (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/Makefile
+++ /dev/null
-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
blob - ba9d3b1a2b268af3d20bb9faf725277c19d87a85 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/argparse.c
+++ /dev/null
-/* [argparse.c wk 17.06.97] Argument Parser for option handling
- * Copyright (C) 1998-2001, 2006-2008, 2012 Free Software Foundation, Inc.
- * Copyright (C) 1997-2001, 2006-2008, 2013-2015 Werner Koch
- *
- * This file is part of JNLIB, which is a subsystem of GnuPG.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of either
- *
- * - the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at
- * your option) any later version.
- *
- * or
- *
- * - 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.
- *
- * or both in parallel, as here.
- *
- * JNLIB 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 copies of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, see <http://www.gnu.org/licenses/>.
- */
-
-/* This file may be used as part of GnuPG or standalone. A GnuPG
- build is detected by the presence of the macro GNUPG_MAJOR_VERSION.
- Some feature are only availalbe in the GnuPG build mode.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <errno.h>
-
-#ifdef GNUPG_MAJOR_VERSION
-# include "libjnlib-config.h"
-# include "mischelp.h"
-# include "stringhelp.h"
-# include "logging.h"
-# ifdef JNLIB_NEED_UTF8CONV
-# include "utf8conv.h"
-# endif
-#endif /*GNUPG_MAJOR_VERSION*/
-
-#include "argparse.h"
-
-/* GnuPG uses GPLv3+ but a standalone version of this defaults to
- GPLv2+ because that is the license of this file. Change this if
- you include it in a program which uses GPLv3. If you don't want to
- set a a copyright string for your usage() you may also hardcode it
- here. */
-#ifndef GNUPG_MAJOR_VERSION
-
-# define ARGPARSE_GPL_VERSION 2
-# define ARGPARSE_CRIGHT_STR "Copyright (C) YEAR NAME"
-
-#else /* Used by GnuPG */
-
-# define ARGPARSE_GPL_VERSION 3
-# define ARGPARSE_CRIGHT_STR "Copyright (C) 2015 Free Software Foundation, Inc."
-
-#endif /*GNUPG_MAJOR_VERSION*/
-
-/* Replacements for standalone builds. */
-#ifndef GNUPG_MAJOR_VERSION
-# ifndef _
-# define _(a) (a)
-# endif
-# ifndef DIM
-# define DIM(v) (sizeof(v)/sizeof((v)[0]))
-# endif
-# define jnlib_malloc(a) malloc ((a))
-# define jnlib_realloc(a,b) realloc ((a), (b))
-# define jnlib_strdup(a) strdup ((a))
-# define jnlib_free(a) free ((a))
-# define jnlib_log_error my_log_error
-# define jnlib_log_bug my_log_bug
-# define trim_spaces(a) my_trim_spaces ((a))
-# define map_static_macro_string(a) (a)
-#endif /*!GNUPG_MAJOR_VERSION*/
-
-
-#define ARGPARSE_STR(v) #v
-#define ARGPARSE_STR2(v) ARGPARSE_STR(v)
-
-
-/* Replacements for standalone builds. */
-#ifndef GNUPG_MAJOR_VERSION
-static void
-my_log_error (const char *fmt, ...)
-{
- va_list arg_ptr ;
-
- va_start (arg_ptr, fmt);
- fprintf (stderr, "%s: ", strusage (11));
- vfprintf (stderr, fmt, arg_ptr);
- va_end (arg_ptr);
-}
-
-static void
-my_log_bug (const char *fmt, ...)
-{
- va_list arg_ptr ;
-
- va_start (arg_ptr, fmt);
- fprintf (stderr, "%s: Ohhhh jeeee: ", strusage (11));
- vfprintf (stderr, fmt, arg_ptr);
- va_end (arg_ptr);
- abort ();
-}
-
-static char *
-my_trim_spaces (char *str)
-{
- char *string, *p, *mark;
-
- string = str;
- /* Find first non space character. */
- for (p=string; *p && isspace (*(unsigned char*)p) ; p++)
- ;
- /* Move characters. */
- for ((mark = NULL); (*string = *p); string++, p++)
- if (isspace (*(unsigned char*)p))
- {
- if (!mark)
- mark = string;
- }
- else
- mark = NULL;
- if (mark)
- *mark = '\0' ; /* Remove trailing spaces. */
-
- return str ;
-}
-
-#endif /*!GNUPG_MAJOR_VERSION*/
-
-
-
-/*********************************
- * @Summary arg_parse
- * #include "argparse.h"
- *
- * typedef struct {
- * char *argc; pointer to argc (value subject to change)
- * char ***argv; pointer to argv (value subject to change)
- * unsigned flags; Global flags (DO NOT CHANGE)
- * int err; print error about last option
- * 1 = warning, 2 = abort
- * int r_opt; return option
- * int r_type; type of return value (0 = no argument found)
- * union {
- * int ret_int;
- * long ret_long
- * ulong ret_ulong;
- * char *ret_str;
- * } r; Return values
- * struct {
- * int idx;
- * const char *last;
- * void *aliases;
- * } internal; DO NOT CHANGE
- * } ARGPARSE_ARGS;
- *
- * typedef struct {
- * int short_opt;
- * const char *long_opt;
- * unsigned flags;
- * } ARGPARSE_OPTS;
- *
- * int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts );
- *
- * @Description
- * This is my replacement for getopt(). See the example for a typical usage.
- * Global flags are:
- * Bit 0 : Do not remove options form argv
- * Bit 1 : Do not stop at last option but return other args
- * with r_opt set to -1.
- * Bit 2 : Assume options and real args are mixed.
- * Bit 3 : Do not use -- to stop option processing.
- * Bit 4 : Do not skip the first arg.
- * Bit 5 : allow usage of long option with only one dash
- * Bit 6 : ignore --version
- * all other bits must be set to zero, this value is modified by the
- * function, so assume this is write only.
- * Local flags (for each option):
- * Bit 2-0 : 0 = does not take an argument
- * 1 = takes int argument
- * 2 = takes string argument
- * 3 = takes long argument
- * 4 = takes ulong argument
- * Bit 3 : argument is optional (r_type will the be set to 0)
- * Bit 4 : allow 0x etc. prefixed values.
- * Bit 6 : Ignore this option
- * Bit 7 : This is a command and not an option
- * You stop the option processing by setting opts to NULL, the function will
- * then return 0.
- * @Return Value
- * Returns the args.r_opt or 0 if ready
- * r_opt may be -2/-7 to indicate an unknown option/command.
- * @See Also
- * ArgExpand
- * @Notes
- * You do not need to process the options 'h', '--help' or '--version'
- * because this function includes standard help processing; but if you
- * specify '-h', '--help' or '--version' you have to do it yourself.
- * The option '--' stops argument processing; if bit 1 is set the function
- * continues to return normal arguments.
- * To process float args or unsigned args you must use a string args and do
- * the conversion yourself.
- * @Example
- *
- * ARGPARSE_OPTS opts[] = {
- * { 'v', "verbose", 0 },
- * { 'd', "debug", 0 },
- * { 'o', "output", 2 },
- * { 'c', "cross-ref", 2|8 },
- * { 'm', "my-option", 1|8 },
- * { 300, "ignored-long-option, ARGPARSE_OP_IGNORE},
- * { 500, "have-no-short-option-for-this-long-option", 0 },
- * {0} };
- * ARGPARSE_ARGS pargs = { &argc, &argv, 0 }
- *
- * while( ArgParse( &pargs, &opts) ) {
- * switch( pargs.r_opt ) {
- * case 'v': opt.verbose++; break;
- * case 'd': opt.debug++; break;
- * case 'o': opt.outfile = pargs.r.ret_str; break;
- * case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
- * case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
- * case 500: opt.a_long_one++; break
- * default : pargs.err = 1; break; -- force warning output --
- * }
- * }
- * if( argc > 1 )
- * log_fatal( "Too many args");
- *
- */
-
-typedef struct alias_def_s *ALIAS_DEF;
-struct alias_def_s {
- ALIAS_DEF next;
- char *name; /* malloced buffer with name, \0, value */
- const char *value; /* ptr into name */
-};
-
-
-/* Object to store the names for the --ignore-invalid-option option.
- This is a simple linked list. */
-typedef struct iio_item_def_s *IIO_ITEM_DEF;
-struct iio_item_def_s
-{
- IIO_ITEM_DEF next;
- char name[]; /* String with the long option name. */
-};
-
-static const char *(*strusage_handler)( int ) = NULL;
-static int (*custom_outfnc) (int, const char *);
-
-static int set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s);
-static void show_help(ARGPARSE_OPTS *opts, unsigned flags);
-static void show_version(void);
-static int writestrings (int is_error, const char *string, ...)
-#if __GNUC__ >= 4
- __attribute__ ((sentinel(0)))
-#endif
- ;
-
-
-void
-argparse_register_outfnc (int (*fnc)(int, const char *))
-{
- custom_outfnc = fnc;
-}
-
-
-/* Write STRING and all following const char * arguments either to
- stdout or, if IS_ERROR is set, to stderr. The list of strings must
- be terminated by a NULL. */
-static int
-writestrings (int is_error, const char *string, ...)
-{
- va_list arg_ptr;
- const char *s;
- int count = 0;
-
- if (string)
- {
- s = string;
- va_start (arg_ptr, string);
- do
- {
- if (custom_outfnc)
- custom_outfnc (is_error? 2:1, s);
- else
- fputs (s, is_error? stderr : stdout);
- count += strlen (s);
- }
- while ((s = va_arg (arg_ptr, const char *)));
- va_end (arg_ptr);
- }
- return count;
-}
-
-
-static void
-flushstrings (int is_error)
-{
- if (custom_outfnc)
- custom_outfnc (is_error? 2:1, NULL);
- else
- fflush (is_error? stderr : stdout);
-}
-
-
-static void
-initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
-{
- if( !(arg->flags & (1<<15)) )
- {
- /* Initialize this instance. */
- arg->internal.idx = 0;
- arg->internal.last = NULL;
- arg->internal.inarg = 0;
- arg->internal.stopped = 0;
- arg->internal.aliases = NULL;
- arg->internal.cur_alias = NULL;
- arg->internal.iio_list = NULL;
- arg->err = 0;
- arg->flags |= 1<<15; /* Mark as initialized. */
- if ( *arg->argc < 0 )
- jnlib_log_bug ("invalid argument for arg_parse\n");
- }
-
-
- if (arg->err)
- {
- /* Last option was erroneous. */
- const char *s;
-
- if (filename)
- {
- if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
- s = _("argument not expected");
- else if ( arg->r_opt == ARGPARSE_READ_ERROR )
- s = _("read error");
- else if ( arg->r_opt == ARGPARSE_KEYWORD_TOO_LONG )
- s = _("keyword too long");
- else if ( arg->r_opt == ARGPARSE_MISSING_ARG )
- s = _("missing argument");
- else if ( arg->r_opt == ARGPARSE_INVALID_ARG )
- s = _("invalid argument");
- else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
- s = _("invalid command");
- else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS )
- s = _("invalid alias definition");
- else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE )
- s = _("out of core");
- else
- s = _("invalid option");
- jnlib_log_error ("%s:%u: %s\n", filename, *lineno, s);
- }
- else
- {
- s = arg->internal.last? arg->internal.last:"[??]";
-
- if ( arg->r_opt == ARGPARSE_MISSING_ARG )
- jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s);
- else if ( arg->r_opt == ARGPARSE_INVALID_ARG )
- jnlib_log_error (_("invalid argument for option \"%.50s\"\n"), s);
- else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
- jnlib_log_error (_("option \"%.50s\" does not expect an "
- "argument\n"), s );
- else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
- jnlib_log_error (_("invalid command \"%.50s\"\n"), s);
- else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_OPTION )
- jnlib_log_error (_("option \"%.50s\" is ambiguous\n"), s);
- else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_COMMAND )
- jnlib_log_error (_("command \"%.50s\" is ambiguous\n"),s );
- else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE )
- jnlib_log_error ("%s\n", _("out of core\n"));
- else
- jnlib_log_error (_("invalid option \"%.50s\"\n"), s);
- }
- if (arg->err != ARGPARSE_PRINT_WARNING)
- exit (2);
- arg->err = 0;
- }
-
- /* Zero out the return value union. */
- arg->r.ret_str = NULL;
- arg->r.ret_long = 0;
-}
-
-
-static void
-store_alias( ARGPARSE_ARGS *arg, char *name, char *value )
-{
- /* TODO: replace this dummy function with a rea one
- * and fix the probelms IRIX has with (ALIAS_DEV)arg..
- * used as lvalue
- */
- (void)arg;
- (void)name;
- (void)value;
-#if 0
- ALIAS_DEF a = jnlib_xmalloc( sizeof *a );
- a->name = name;
- a->value = value;
- a->next = (ALIAS_DEF)arg->internal.aliases;
- (ALIAS_DEF)arg->internal.aliases = a;
-#endif
-}
-
-
-/* Return true if KEYWORD is in the ignore-invalid-option list. */
-static int
-ignore_invalid_option_p (ARGPARSE_ARGS *arg, const char *keyword)
-{
- IIO_ITEM_DEF item = arg->internal.iio_list;
-
- for (; item; item = item->next)
- if (!strcmp (item->name, keyword))
- return 1;
- return 0;
-}
-
-
-/* Add the keywords up to the next LF to the list of to be ignored
- options. After returning FP will either be at EOF or the next
- character read wll be the first of a new line. The function
- returns 0 on success or true on malloc failure. */
-static int
-ignore_invalid_option_add (ARGPARSE_ARGS *arg, FILE *fp)
-{
- IIO_ITEM_DEF item;
- int c;
- char name[100];
- int namelen = 0;
- int ready = 0;
- enum { skipWS, collectNAME, skipNAME, addNAME} state = skipWS;
-
- while (!ready)
- {
- c = getc (fp);
- if (c == '\n')
- ready = 1;
- else if (c == EOF)
- {
- c = '\n';
- ready = 1;
- }
- again:
- switch (state)
- {
- case skipWS:
- if (!isascii (c) || !isspace(c))
- {
- namelen = 0;
- state = collectNAME;
- goto again;
- }
- break;
-
- case collectNAME:
- if (isspace (c))
- {
- state = addNAME;
- goto again;
- }
- else if (namelen < DIM(name)-1) {
- assert(namelen < (sizeof(name) - 1));
- name[namelen++] = c;
- } else /* Too long. */
- state = skipNAME;
- break;
-
- case skipNAME:
- if (isspace (c))
- {
- state = skipWS;
- goto again;
- }
- break;
-
- case addNAME:
- name[namelen] = 0;
- if (!ignore_invalid_option_p (arg, name))
- {
- item = jnlib_malloc (sizeof *item + namelen + 1);
- if (!item)
- return 1;
- strlcpy (item->name, name, namelen + 1);
- item->next = (IIO_ITEM_DEF)arg->internal.iio_list;
- arg->internal.iio_list = item;
- }
- state = skipWS;
- goto again;
- }
- }
- return 0;
-}
-
-
-/* Clear the entire ignore-invalid-option list. */
-static void
-ignore_invalid_option_clear (ARGPARSE_ARGS *arg)
-{
- IIO_ITEM_DEF item, tmpitem;
-
- for (item = arg->internal.iio_list; item; item = tmpitem)
- {
- tmpitem = item->next;
- jnlib_free (item);
- }
- arg->internal.iio_list = NULL;
-}
-
-
-
-/****************
- * Get options from a file.
- * Lines starting with '#' are comment lines.
- * Syntax is simply a keyword and the argument.
- * Valid keywords are all keywords from the long_opt list without
- * the leading dashes. The special keywords "help", "warranty" and "version"
- * are not valid here.
- * The special keyword "alias" may be used to store alias definitions,
- * which are later expanded like long options.
- * The option
- * ignore-invalid-option OPTIONNAMEs
- * is recognized and updates a list of option which should be ignored if they
- * are not defined.
- * Caller must free returned strings.
- * If called with FP set to NULL command line args are parse instead.
- *
- * Q: Should we allow the syntax
- * keyword = value
- * and accept for boolean options a value of 1/0, yes/no or true/false?
- * Note: Abbreviation of options is here not allowed.
- */
-int
-optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
- ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
-{
- int state, i, c;
- int idx=0;
- char keyword[100];
- char *buffer = NULL;
- size_t buflen = 0;
- int in_alias=0;
-
- if (!fp) /* Divert to to arg_parse() in this case. */
- return arg_parse (arg, opts);
-
- initialize (arg, filename, lineno);
-
- /* Find the next keyword. */
- state = i = 0;
- for (;;)
- {
- c = getc (fp);
- if (c == '\n' || c== EOF )
- {
- if ( c != EOF )
- ++*lineno;
- if (state == -1)
- break;
- else if (state == 2)
- {
- keyword[i] = 0;
- for (i=0; opts[i].short_opt; i++ )
- {
- if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
- break;
- }
- idx = i;
- arg->r_opt = opts[idx].short_opt;
- if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
- {
- state = i = 0;
- continue;
- }
- else if (!opts[idx].short_opt )
- {
- if (!strcmp (keyword, "ignore-invalid-option"))
- {
- /* No argument - ignore this meta option. */
- state = i = 0;
- continue;
- }
- else if (ignore_invalid_option_p (arg, keyword))
- {
- /* This invalid option is in the iio list. */
- state = i = 0;
- continue;
- }
- arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
- ? ARGPARSE_INVALID_COMMAND
- : ARGPARSE_INVALID_OPTION);
- }
- else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
- arg->r_type = 0; /* Does not take an arg. */
- else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL) )
- arg->r_type = 0; /* Arg is optional. */
- else
- arg->r_opt = ARGPARSE_MISSING_ARG;
-
- break;
- }
- else if (state == 3)
- {
- /* No argument found. */
- if (in_alias)
- arg->r_opt = ARGPARSE_MISSING_ARG;
- else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
- arg->r_type = 0; /* Does not take an arg. */
- else if ((opts[idx].flags & ARGPARSE_OPT_OPTIONAL))
- arg->r_type = 0; /* No optional argument. */
- else
- arg->r_opt = ARGPARSE_MISSING_ARG;
-
- break;
- }
- else if (state == 4)
- {
- /* Has an argument. */
- if (in_alias)
- {
- if (!buffer)
- arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
- else
- {
- char *p;
-
- buffer[i] = 0;
- p = strpbrk (buffer, " \t");
- if (p)
- {
- *p++ = 0;
- trim_spaces (p);
- }
- if (!p || !*p)
- {
- jnlib_free (buffer);
- arg->r_opt = ARGPARSE_INVALID_ALIAS;
- }
- else
- {
- store_alias (arg, buffer, p);
- }
- }
- }
- else if (!(opts[idx].flags & ARGPARSE_TYPE_MASK))
- arg->r_opt = ARGPARSE_UNEXPECTED_ARG;
- else
- {
- char *p;
-
- if (!buffer)
- {
- keyword[i] = 0;
- buffer = jnlib_strdup (keyword);
- if (!buffer)
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- }
- else
- buffer[i] = 0;
-
- if (buffer)
- {
- trim_spaces (buffer);
- p = buffer;
- if (*p == '"')
- {
- /* Remove quotes. */
- p++;
- if (*p && p[strlen(p)-1] == '\"' )
- p[strlen(p)-1] = 0;
- }
- if (!set_opt_arg (arg, opts[idx].flags, p))
- jnlib_free(buffer);
- }
- }
- break;
- }
- else if (c == EOF)
- {
- ignore_invalid_option_clear (arg);
- if (ferror (fp))
- arg->r_opt = ARGPARSE_READ_ERROR;
- else
- arg->r_opt = 0; /* EOF. */
- break;
- }
- state = 0;
- i = 0;
- }
- else if (state == -1)
- ; /* Skip. */
- else if (state == 0 && isascii (c) && isspace(c))
- ; /* Skip leading white space. */
- else if (state == 0 && c == '#' )
- state = 1; /* Start of a comment. */
- else if (state == 1)
- ; /* Skip comments. */
- else if (state == 2 && isascii (c) && isspace(c))
- {
- /* Check keyword. */
- keyword[i] = 0;
- for (i=0; opts[i].short_opt; i++ )
- if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword))
- break;
- idx = i;
- arg->r_opt = opts[idx].short_opt;
- if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
- {
- state = 1; /* Process like a comment. */
- }
- else if (!opts[idx].short_opt)
- {
- if (!strcmp (keyword, "alias"))
- {
- in_alias = 1;
- state = 3;
- }
- else if (!strcmp (keyword, "ignore-invalid-option"))
- {
- if (ignore_invalid_option_add (arg, fp))
- {
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
- }
- state = i = 0;
- ++*lineno;
- }
- else if (ignore_invalid_option_p (arg, keyword))
- state = 1; /* Process like a comment. */
- else
- {
- arg->r_opt = ((opts[idx].flags & ARGPARSE_OPT_COMMAND)
- ? ARGPARSE_INVALID_COMMAND
- : ARGPARSE_INVALID_OPTION);
- state = -1; /* Skip rest of line and leave. */
- }
- }
- else
- state = 3;
- }
- else if (state == 3)
- {
- /* Skip leading spaces of the argument. */
- if (!isascii (c) || !isspace(c))
- {
- i = 0;
- keyword[i++] = c;
- state = 4;
- }
- }
- else if (state == 4)
- {
- /* Collect the argument. */
- if (buffer)
- {
- if (i < buflen-1)
- buffer[i++] = c;
- else
- {
- char *tmp;
- size_t tmplen = buflen + 50;
-
- tmp = jnlib_realloc (buffer, tmplen);
- if (tmp)
- {
- buflen = tmplen;
- buffer = tmp;
- buffer[i++] = c;
- }
- else
- {
- jnlib_free (buffer);
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
- }
- }
- }
- else if (i < DIM(keyword)-1)
- keyword[i++] = c;
- else
- {
- size_t tmplen = DIM(keyword) + 50;
- buffer = jnlib_malloc (tmplen);
- if (buffer)
- {
- buflen = tmplen;
- memcpy(buffer, keyword, i);
- buffer[i++] = c;
- }
- else
- {
- arg->r_opt = ARGPARSE_OUT_OF_CORE;
- break;
- }
- }
- }
- else if (i >= DIM(keyword)-1)
- {
- arg->r_opt = ARGPARSE_KEYWORD_TOO_LONG;
- state = -1; /* Skip rest of line and leave. */
- }
- else
- {
- keyword[i++] = c;
- state = 2;
- }
- }
-
- return arg->r_opt;
-}
-
-
-
-static int
-find_long_option( ARGPARSE_ARGS *arg,
- ARGPARSE_OPTS *opts, const char *keyword )
-{
- int i;
- size_t n;
-
- (void)arg;
-
- /* Would be better if we can do a binary search, but it is not
- possible to reorder our option table because we would mess
- up our help strings - What we can do is: Build a nice option
- lookup table wehn this function is first invoked */
- if( !*keyword )
- return -1;
- for(i=0; opts[i].short_opt; i++ )
- if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
- return i;
-#if 0
- {
- ALIAS_DEF a;
- /* see whether it is an alias */
- for( a = args->internal.aliases; a; a = a->next ) {
- if( !strcmp( a->name, keyword) ) {
- /* todo: must parse the alias here */
- args->internal.cur_alias = a;
- return -3; /* alias available */
- }
- }
- }
-#endif
- /* not found, see whether it is an abbreviation */
- /* aliases may not be abbreviated */
- n = strlen( keyword );
- for(i=0; opts[i].short_opt; i++ ) {
- if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) {
- int j;
- for(j=i+1; opts[j].short_opt; j++ ) {
- if( opts[j].long_opt
- && !strncmp( opts[j].long_opt, keyword, n ) )
- return -2; /* abbreviation is ambiguous */
- }
- return i;
- }
- }
- return -1; /* Not found. */
-}
-
-int
-arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
-{
- int idx;
- int argc;
- char **argv;
- char *s, *s2;
- int i;
-
- initialize( arg, NULL, NULL );
- argc = *arg->argc;
- argv = *arg->argv;
- idx = arg->internal.idx;
-
- if (!idx && argc && !(arg->flags & ARGPARSE_FLAG_ARG0))
- {
- /* Skip the first argument. */
- argc--; argv++; idx++;
- }
-
- next_one:
- if (!argc)
- {
- /* No more args. */
- arg->r_opt = 0;
- goto leave; /* Ready. */
- }
-
- s = *argv;
- arg->internal.last = s;
-
- if (arg->internal.stopped && (arg->flags & ARGPARSE_FLAG_ALL))
- {
- arg->r_opt = ARGPARSE_IS_ARG; /* Not an option but an argument. */
- arg->r_type = 2;
- arg->r.ret_str = s;
- argc--; argv++; idx++; /* set to next one */
- }
- else if( arg->internal.stopped )
- {
- arg->r_opt = 0;
- goto leave; /* Ready. */
- }
- else if ( *s == '-' && s[1] == '-' )
- {
- /* Long option. */
- char *argpos;
-
- arg->internal.inarg = 0;
- if (!s[2] && !(arg->flags & ARGPARSE_FLAG_NOSTOP))
- {
- /* Stop option processing. */
- arg->internal.stopped = 1;
- arg->flags |= ARGPARSE_FLAG_STOP_SEEN;
- argc--; argv++; idx++;
- goto next_one;
- }
-
- argpos = strchr( s+2, '=' );
- if ( argpos )
- *argpos = 0;
- i = find_long_option ( arg, opts, s+2 );
- if ( argpos )
- *argpos = '=';
-
- if ( i < 0 && !strcmp ( "help", s+2) )
- show_help (opts, arg->flags);
- else if ( i < 0 && !strcmp ( "version", s+2) )
- {
- if (!(arg->flags & ARGPARSE_FLAG_NOVERSION))
- {
- show_version ();
- exit(0);
- }
- }
- else if ( i < 0 && !strcmp( "warranty", s+2))
- {
- writestrings (0, strusage (16), "\n", NULL);
- exit (0);
- }
- else if ( i < 0 && !strcmp( "dump-options", s+2) )
- {
- for (i=0; opts[i].short_opt; i++ )
- {
- if (opts[i].long_opt && !(opts[i].flags & ARGPARSE_OPT_IGNORE))
- writestrings (0, "--", opts[i].long_opt, "\n", NULL);
- }
- writestrings (0, "--dump-options\n--help\n--version\n--warranty\n",
- NULL);
- exit (0);
- }
-
- if ( i == -2 )
- arg->r_opt = ARGPARSE_AMBIGUOUS_OPTION;
- else if ( i == -1 )
- {
- arg->r_opt = ARGPARSE_INVALID_OPTION;
- arg->r.ret_str = s+2;
- }
- else
- arg->r_opt = opts[i].short_opt;
- if ( i < 0 )
- ;
- else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
- {
- if ( argpos )
- {
- s2 = argpos+1;
- if ( !*s2 )
- s2 = NULL;
- }
- else
- s2 = argv[1];
- if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- arg->r_type = ARGPARSE_TYPE_NONE; /* Argument is optional. */
- }
- else if ( !s2 )
- {
- arg->r_opt = ARGPARSE_MISSING_ARG;
- }
- else if ( !argpos && *s2 == '-'
- && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- /* The argument is optional and the next seems to be an
- option. We do not check this possible option but
- assume no argument */
- arg->r_type = ARGPARSE_TYPE_NONE;
- }
- else
- {
- set_opt_arg (arg, opts[i].flags, s2);
- if ( !argpos )
- {
- argc--; argv++; idx++; /* Skip one. */
- }
- }
- }
- else
- {
- /* Does not take an argument. */
- if ( argpos )
- arg->r_type = ARGPARSE_UNEXPECTED_ARG;
- else
- arg->r_type = 0;
- }
- argc--; argv++; idx++; /* Set to next one. */
- }
- else if ( (*s == '-' && s[1]) || arg->internal.inarg )
- {
- /* Short option. */
- int dash_kludge = 0;
-
- i = 0;
- if ( !arg->internal.inarg )
- {
- arg->internal.inarg++;
- if ( (arg->flags & ARGPARSE_FLAG_ONEDASH) )
- {
- for (i=0; opts[i].short_opt; i++ )
- if ( opts[i].long_opt && !strcmp (opts[i].long_opt, s+1))
- {
- dash_kludge = 1;
- break;
- }
- }
- }
- s += arg->internal.inarg;
-
- if (!dash_kludge )
- {
- for (i=0; opts[i].short_opt; i++ )
- if ( opts[i].short_opt == *s )
- break;
- }
-
- if ( !opts[i].short_opt && ( *s == 'h' || *s == '?' ) )
- show_help (opts, arg->flags);
-
- arg->r_opt = opts[i].short_opt;
- if (!opts[i].short_opt )
- {
- arg->r_opt = (opts[i].flags & ARGPARSE_OPT_COMMAND)?
- ARGPARSE_INVALID_COMMAND:ARGPARSE_INVALID_OPTION;
- arg->internal.inarg++; /* Point to the next arg. */
- arg->r.ret_str = s;
- }
- else if ( (opts[i].flags & ARGPARSE_TYPE_MASK) )
- {
- if ( s[1] && !dash_kludge )
- {
- s2 = s+1;
- set_opt_arg (arg, opts[i].flags, s2);
- }
- else
- {
- s2 = argv[1];
- if ( !s2 && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- arg->r_type = ARGPARSE_TYPE_NONE;
- }
- else if ( !s2 )
- {
- arg->r_opt = ARGPARSE_MISSING_ARG;
- }
- else if ( *s2 == '-' && s2[1]
- && (opts[i].flags & ARGPARSE_OPT_OPTIONAL) )
- {
- /* The argument is optional and the next seems to
- be an option. We do not check this possible
- option but assume no argument. */
- arg->r_type = ARGPARSE_TYPE_NONE;
- }
- else
- {
- set_opt_arg (arg, opts[i].flags, s2);
- argc--; argv++; idx++; /* Skip one. */
- }
- }
- s = "x"; /* This is so that !s[1] yields false. */
- }
- else
- {
- /* Does not take an argument. */
- arg->r_type = ARGPARSE_TYPE_NONE;
- arg->internal.inarg++; /* Point to the next arg. */
- }
- if ( !s[1] || dash_kludge )
- {
- /* No more concatenated short options. */
- arg->internal.inarg = 0;
- argc--; argv++; idx++;
- }
- }
- else if ( arg->flags & ARGPARSE_FLAG_MIXED )
- {
- arg->r_opt = ARGPARSE_IS_ARG;
- arg->r_type = 2;
- arg->r.ret_str = s;
- argc--; argv++; idx++; /* Set to next one. */
- }
- else
- {
- arg->internal.stopped = 1; /* Stop option processing. */
- goto next_one;
- }
-
- leave:
- *arg->argc = argc;
- *arg->argv = argv;
- arg->internal.idx = idx;
- return arg->r_opt;
-}
-
-
-/* Returns: -1 on error, 0 for an integer type and 1 for a non integer
- type argument. */
-static int
-set_opt_arg (ARGPARSE_ARGS *arg, unsigned flags, char *s)
-{
- int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10;
- long l;
-
- switch ( (arg->r_type = (flags & ARGPARSE_TYPE_MASK)) )
- {
- case ARGPARSE_TYPE_LONG:
- case ARGPARSE_TYPE_INT:
- errno = 0;
- l = strtol (s, NULL, base);
- if ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE)
- {
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- if (arg->r_type == ARGPARSE_TYPE_LONG)
- arg->r.ret_long = l;
- else if ( (l < 0 && l < INT_MIN) || l > INT_MAX )
- {
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- else
- arg->r.ret_int = (int)l;
- return 0;
-
- case ARGPARSE_TYPE_ULONG:
- while (isascii (*s) && isspace(*s))
- s++;
- if (*s == '-')
- {
- arg->r.ret_ulong = 0;
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- errno = 0;
- arg->r.ret_ulong = strtoul (s, NULL, base);
- if (arg->r.ret_ulong == ULONG_MAX && errno == ERANGE)
- {
- arg->r_opt = ARGPARSE_INVALID_ARG;
- return -1;
- }
- return 0;
-
- case ARGPARSE_TYPE_STRING:
- default:
- arg->r.ret_str = s;
- return 1;
- }
-}
-
-
-static size_t
-long_opt_strlen( ARGPARSE_OPTS *o )
-{
- size_t n = strlen (o->long_opt);
-
- if ( o->description && *o->description == '|' )
- {
- const char *s;
-#ifdef JNLIB_NEED_UTF8CONV
- int is_utf8 = is_native_utf8 ();
-#endif
-
- s=o->description+1;
- if ( *s != '=' )
- n++;
- /* For a (mostly) correct length calculation we exclude
- continuation bytes (10xxxxxx) if we are on a native utf8
- terminal. */
- for (; *s && *s != '|'; s++ )
-#ifdef JNLIB_NEED_UTF8CONV
- if ( is_utf8 && (*s&0xc0) != 0x80 )
-#endif
- n++;
- }
- return n;
-}
-
-
-/****************
- * Print formatted help. The description string has some special
- * meanings:
- * - A description string which is "@" suppresses help output for
- * this option
- * - a description,ine which starts with a '@' and is followed by
- * any other characters is printed as is; this may be used for examples
- * ans such.
- * - A description which starts with a '|' outputs the string between this
- * bar and the next one as arguments of the long option.
- */
-static void
-show_help (ARGPARSE_OPTS *opts, unsigned int flags)
-{
- const char *s;
- char tmp[2];
-
- show_version ();
- writestrings (0, "\n", NULL);
- s = strusage (42);
- if (s && *s == '1')
- {
- s = strusage (40);
- writestrings (1, s, NULL);
- if (*s && s[strlen(s)] != '\n')
- writestrings (1, "\n", NULL);
- }
- s = strusage(41);
- writestrings (0, s, "\n", NULL);
- if ( opts[0].description )
- {
- /* Auto format the option description. */
- int i,j, indent;
-
- /* Get max. length of long options. */
- for (i=indent=0; opts[i].short_opt; i++ )
- {
- if ( opts[i].long_opt )
- if ( !opts[i].description || *opts[i].description != '@' )
- if ( (j=long_opt_strlen(opts+i)) > indent && j < 35 )
- indent = j;
- }
-
- /* Example: " -v, --verbose Viele Sachen ausgeben" */
- indent += 10;
- if ( *opts[0].description != '@' )
- writestrings (0, "Options:", "\n", NULL);
- for (i=0; opts[i].short_opt; i++ )
- {
- s = map_static_macro_string (_( opts[i].description ));
- if ( s && *s== '@' && !s[1] ) /* Hide this line. */
- continue;
- if ( s && *s == '@' ) /* Unindented comment only line. */
- {
- for (s++; *s; s++ )
- {
- if ( *s == '\n' )
- {
- if( s[1] )
- writestrings (0, "\n", NULL);
- }
- else
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- }
- writestrings (0, "\n", NULL);
- continue;
- }
-
- j = 3;
- if ( opts[i].short_opt < 256 )
- {
- tmp[0] = opts[i].short_opt;
- tmp[1] = 0;
- writestrings (0, " -", tmp, NULL );
- if ( !opts[i].long_opt )
- {
- if (s && *s == '|' )
- {
- writestrings (0, " ", NULL); j++;
- for (s++ ; *s && *s != '|'; s++, j++ )
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- if ( *s )
- s++;
- }
- }
- }
- else
- writestrings (0, " ", NULL);
- if ( opts[i].long_opt )
- {
- tmp[0] = opts[i].short_opt < 256?',':' ';
- tmp[1] = 0;
- j += writestrings (0, tmp, " --", opts[i].long_opt, NULL);
- if (s && *s == '|' )
- {
- if ( *++s != '=' )
- {
- writestrings (0, " ", NULL);
- j++;
- }
- for ( ; *s && *s != '|'; s++, j++ )
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- if ( *s )
- s++;
- }
- writestrings (0, " ", NULL);
- j += 3;
- }
- for (;j < indent; j++ )
- writestrings (0, " ", NULL);
- if ( s )
- {
- if ( *s && j > indent )
- {
- writestrings (0, "\n", NULL);
- for (j=0;j < indent; j++ )
- writestrings (0, " ", NULL);
- }
- for (; *s; s++ )
- {
- if ( *s == '\n' )
- {
- if ( s[1] )
- {
- writestrings (0, "\n", NULL);
- for (j=0; j < indent; j++ )
- writestrings (0, " ", NULL);
- }
- }
- else
- {
- tmp[0] = *s;
- tmp[1] = 0;
- writestrings (0, tmp, NULL);
- }
- }
- }
- writestrings (0, "\n", NULL);
- }
- if ( (flags & ARGPARSE_FLAG_ONEDASH) )
- writestrings (0, "\n(A single dash may be used "
- "instead of the double ones)\n", NULL);
- }
- if ( (s=strusage(19)) )
- {
- writestrings (0, "\n", NULL);
- writestrings (0, s, NULL);
- }
- flushstrings (0);
- exit(0);
-}
-
-static void
-show_version (void)
-{
- const char *s;
- int i;
-
- /* Version line. */
- writestrings (0, strusage (11), NULL);
- if ((s=strusage (12)))
- writestrings (0, " (", s, ")", NULL);
- writestrings (0, " ", strusage (13), "\n", NULL);
- /* Additional version lines. */
- for (i=20; i < 30; i++)
- if ((s=strusage (i)))
- writestrings (0, s, "\n", NULL);
- /* Copyright string. */
- if ((s=strusage (14)))
- writestrings (0, s, "\n", NULL);
- /* Licence string. */
- if( (s=strusage (10)) )
- writestrings (0, s, "\n", NULL);
- /* Copying conditions. */
- if ( (s=strusage(15)) )
- writestrings (0, s, NULL);
- /* Thanks. */
- if ((s=strusage(18)))
- writestrings (0, s, NULL);
- /* Additional program info. */
- for (i=30; i < 40; i++ )
- if ( (s=strusage (i)) )
- writestrings (0, s, NULL);
- flushstrings (0);
-}
-
-
-void
-usage (int level)
-{
- const char *p;
-
- if (!level)
- {
- writestrings (1, strusage(11), " ", strusage(13), "; ",
- strusage (14), "\n", NULL);
- flushstrings (1);
- }
- else if (level == 1)
- {
- p = strusage (40);
- writestrings (1, p, NULL);
- if (*p && p[strlen(p)] != '\n')
- writestrings (1, "\n", NULL);
- exit (2);
- }
- else if (level == 2)
- {
- p = strusage (42);
- if (p && *p == '1')
- {
- p = strusage (40);
- writestrings (1, p, NULL);
- if (*p && p[strlen(p)] != '\n')
- writestrings (1, "\n", NULL);
- }
- writestrings (0, strusage(41), "\n", NULL);
- exit (0);
- }
-}
-
-/* Level
- * 0: Print copyright string to stderr
- * 1: Print a short usage hint to stderr and terminate
- * 2: Print a long usage hint to stdout and terminate
- * 10: Return license info string
- * 11: Return the name of the program
- * 12: Return optional name of package which includes this program.
- * 13: version string
- * 14: copyright string
- * 15: Short copying conditions (with LFs)
- * 16: Long copying conditions (with LFs)
- * 17: Optional printable OS name
- * 18: Optional thanks list (with LFs)
- * 19: Bug report info
- *20..29: Additional lib version strings.
- *30..39: Additional program info (with LFs)
- * 40: short usage note (with LF)
- * 41: long usage note (with LF)
- * 42: Flag string:
- * First char is '1':
- * The short usage notes needs to be printed
- * before the long usage note.
- */
-const char *
-strusage( int level )
-{
- const char *p = strusage_handler? strusage_handler(level) : NULL;
-
- if ( p )
- return map_static_macro_string (p);
-
- switch ( level )
- {
-
- case 10:
-#if ARGPARSE_GPL_VERSION == 3
- p = ("License GPLv3+: GNU GPL version 3 or later "
- "<http://gnu.org/licenses/gpl.html>");
-#else
- p = ("License GPLv2+: GNU GPL version 2 or later "
- "<http://gnu.org/licenses/>");
-#endif
- break;
- case 11: p = "foo"; break;
- case 13: p = "0.0"; break;
- case 14: p = ARGPARSE_CRIGHT_STR; break;
- case 15: p =
-"This is free software: you are free to change and redistribute it.\n"
-"There is NO WARRANTY, to the extent permitted by law.\n";
- break;
- case 16: p =
-"This is free software; you can redistribute it and/or modify\n"
-"it under the terms of the GNU General Public License as published by\n"
-"the Free Software Foundation; either version "
-ARGPARSE_STR2(ARGPARSE_GPL_VERSION)
-" of the License, or\n"
-"(at your option) any later version.\n\n"
-"It is distributed in the hope that it will be useful,\n"
-"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
-"GNU General Public License for more details.\n\n"
-"You should have received a copy of the GNU General Public License\n"
-"along with this software. If not, see <http://www.gnu.org/licenses/>.\n";
- break;
- case 40: /* short and long usage */
- case 41: p = ""; break;
- }
-
- return p;
-}
-
-
-/* Set the usage handler. This function is basically a constructor. */
-void
-set_strusage ( const char *(*f)( int ) )
-{
- strusage_handler = f;
-}
-
-
-#ifdef TEST
-static struct {
- int verbose;
- int debug;
- char *outfile;
- char *crf;
- int myopt;
- int echo;
- int a_long_one;
-} opt;
-
-int
-main(int argc, char **argv)
-{
- ARGPARSE_OPTS opts[] = {
- ARGPARSE_x('v', "verbose", NONE, 0, "Laut sein"),
- ARGPARSE_s_n('e', "echo" , ("Zeile ausgeben, damit wir sehen, "
- "was wir eingegeben haben")),
- ARGPARSE_s_n('d', "debug", "Debug\nfalls mal etwas\nschief geht"),
- ARGPARSE_s_s('o', "output", 0 ),
- ARGPARSE_o_s('c', "cross-ref", "cross-reference erzeugen\n" ),
- /* Note that on a non-utf8 terminal the ß might garble the output. */
- ARGPARSE_s_n('s', "street","|Straße|set the name of the street to Straße"),
- ARGPARSE_o_i('m', "my-option", 0),
- ARGPARSE_s_n(500, "a-long-option", 0 ),
- ARGPARSE_end()
- };
- ARGPARSE_ARGS pargs = { &argc, &argv, (ARGPARSE_FLAG_ALL
- | ARGPARSE_FLAG_MIXED
- | ARGPARSE_FLAG_ONEDASH) };
- int i;
-
- while (arg_parse (&pargs, opts))
- {
- switch (pargs.r_opt)
- {
- case ARGPARSE_IS_ARG :
- printf ("arg='%s'\n", pargs.r.ret_str);
- break;
- case 'v': opt.verbose++; break;
- case 'e': opt.echo++; break;
- case 'd': opt.debug++; break;
- case 'o': opt.outfile = pargs.r.ret_str; break;
- case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
- case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
- case 500: opt.a_long_one++; break;
- default : pargs.err = ARGPARSE_PRINT_WARNING; break;
- }
- }
- for (i=0; i < argc; i++ )
- printf ("%3d -> (%s)\n", i, argv[i] );
- puts ("Options:");
- if (opt.verbose)
- printf (" verbose=%d\n", opt.verbose );
- if (opt.debug)
- printf (" debug=%d\n", opt.debug );
- if (opt.outfile)
- printf (" outfile='%s'\n", opt.outfile );
- if (opt.crf)
- printf (" crffile='%s'\n", opt.crf );
- if (opt.myopt)
- printf (" myopt=%d\n", opt.myopt );
- if (opt.a_long_one)
- printf (" a-long-one=%d\n", opt.a_long_one );
- if (opt.echo)
- printf (" echo=%d\n", opt.echo );
-
- return 0;
-}
-#endif /*TEST*/
-
-/**** bottom of file ****/
blob - b4dc253730009daf43fa23e2d04231241d888abc (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/argparse.h
+++ /dev/null
-/* argparse.h - Argument parser for option handling.
- * Copyright (C) 1998,1999,2000,2001,2006 Free Software Foundation, Inc.
- *
- * This file is part of JNLIB, which is a subsystem of GnuPG.
- *
- * JNLIB is free software; you can redistribute it and/or modify it
- * under the terms of either
- *
- * - the GNU Lesser General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at
- * your option) any later version.
- *
- * or
- *
- * - 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.
- *
- * or both in parallel, as here.
- *
- * JNLIB 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 copies of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LIBJNLIB_ARGPARSE_H
-#define LIBJNLIB_ARGPARSE_H
-
-#include <stdio.h>
-
-typedef struct
-{
- int *argc; /* Pointer to ARGC (value subject to change). */
- char ***argv; /* Pointer to ARGV (value subject to change). */
- unsigned int flags; /* Global flags. May be set prior to calling the
- parser. The parser may change the value. */
- int err; /* Print error description for last option.
- Either 0, ARGPARSE_PRINT_WARNING or
- ARGPARSE_PRINT_ERROR. */
-
- int r_opt; /* Returns option code. */
- int r_type; /* Returns type of option value. */
- union {
- int ret_int;
- long ret_long;
- unsigned long ret_ulong;
- char *ret_str;
- } r; /* Return values */
-
- struct {
- int idx;
- int inarg;
- int stopped;
- const char *last;
- void *aliases;
- const void *cur_alias;
- void *iio_list;
- } internal; /* Private - do not change. */
-} ARGPARSE_ARGS;
-
-typedef struct
-{
- int short_opt;
- const char *long_opt;
- unsigned int flags;
- const char *description; /* Optional option description. */
-} ARGPARSE_OPTS;
-
-
-/* Global flags (ARGPARSE_ARGS). */
-#define ARGPARSE_FLAG_KEEP 1 /* Do not remove options form argv. */
-#define ARGPARSE_FLAG_ALL 2 /* Do not stop at last option but return
- remaining args with R_OPT set to -1. */
-#define ARGPARSE_FLAG_MIXED 4 /* Assume options and args are mixed. */
-#define ARGPARSE_FLAG_NOSTOP 8 /* Do not stop processing at "--". */
-#define ARGPARSE_FLAG_ARG0 16 /* Do not skip the first arg. */
-#define ARGPARSE_FLAG_ONEDASH 32 /* Allow long options with one dash. */
-#define ARGPARSE_FLAG_NOVERSION 64 /* No output for "--version". */
-
-#define ARGPARSE_FLAG_STOP_SEEN 256 /* Set to true if a "--" has been seen. */
-
-/* Flags for each option (ARGPARSE_OPTS). The type code may be
- ORed with the OPT flags. */
-#define ARGPARSE_TYPE_NONE 0 /* Does not take an argument. */
-#define ARGPARSE_TYPE_INT 1 /* Takes an int argument. */
-#define ARGPARSE_TYPE_STRING 2 /* Takes a string argument. */
-#define ARGPARSE_TYPE_LONG 3 /* Takes a long argument. */
-#define ARGPARSE_TYPE_ULONG 4 /* Takes an unsigned long argument. */
-#define ARGPARSE_OPT_OPTIONAL (1<<3) /* Argument is optional. */
-#define ARGPARSE_OPT_PREFIX (1<<4) /* Allow 0x etc. prefixed values. */
-#define ARGPARSE_OPT_IGNORE (1<<6) /* Ignore command or option. */
-#define ARGPARSE_OPT_COMMAND (1<<7) /* The argument is a command. */
-
-#define ARGPARSE_TYPE_MASK 7 /* Mask for the type values (internal). */
-
-/* A set of macros to make option definitions easier to read. */
-#define ARGPARSE_x(s,l,t,f,d) \
- { (s), (l), ARGPARSE_TYPE_ ## t | (f), (d) }
-
-#define ARGPARSE_s(s,l,t,d) \
- { (s), (l), ARGPARSE_TYPE_ ## t, (d) }
-#define ARGPARSE_s_n(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_NONE, (d) }
-#define ARGPARSE_s_i(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_INT, (d) }
-#define ARGPARSE_s_s(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_STRING, (d) }
-#define ARGPARSE_s_l(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_LONG, (d) }
-#define ARGPARSE_s_u(s,l,d) \
- { (s), (l), ARGPARSE_TYPE_ULONG, (d) }
-
-#define ARGPARSE_o(s,l,t,d) \
- { (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_n(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_i(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_s(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_l(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_OPTIONAL), (d) }
-#define ARGPARSE_o_u(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_OPTIONAL), (d) }
-
-#define ARGPARSE_p(s,l,t,d) \
- { (s), (l), (ARGPARSE_TYPE_ ## t | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_n(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_i(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_INT | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_s(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_STRING | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_l(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_LONG | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_p_u(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_ULONG | ARGPARSE_OPT_PREFIX), (d) }
-
-#define ARGPARSE_op(s,l,t,d) \
- { (s), (l), (ARGPARSE_TYPE_ ## t \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_n(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_i(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_INT \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_s(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_STRING \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_l(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_LONG \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-#define ARGPARSE_op_u(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_ULONG \
- | ARGPARSE_OPT_OPTIONAL | ARGPARSE_OPT_PREFIX), (d) }
-
-#define ARGPARSE_c(s,l,d) \
- { (s), (l), (ARGPARSE_TYPE_NONE | ARGPARSE_OPT_COMMAND), (d) }
-
-#define ARGPARSE_ignore(s,l) \
- { (s), (l), (ARGPARSE_OPT_IGNORE), "@" }
-
-#define ARGPARSE_group(s,d) \
- { (s), NULL, 0, (d) }
-
-#define ARGPARSE_end() { 0, NULL, 0, NULL }
-
-
-/* Other constants. */
-#define ARGPARSE_PRINT_WARNING 1
-#define ARGPARSE_PRINT_ERROR 2
-
-
-/* Error values. */
-#define ARGPARSE_IS_ARG (-1)
-#define ARGPARSE_INVALID_OPTION (-2)
-#define ARGPARSE_MISSING_ARG (-3)
-#define ARGPARSE_KEYWORD_TOO_LONG (-4)
-#define ARGPARSE_READ_ERROR (-5)
-#define ARGPARSE_UNEXPECTED_ARG (-6)
-#define ARGPARSE_INVALID_COMMAND (-7)
-#define ARGPARSE_AMBIGUOUS_OPTION (-8)
-#define ARGPARSE_AMBIGUOUS_COMMAND (-9)
-#define ARGPARSE_INVALID_ALIAS (-10)
-#define ARGPARSE_OUT_OF_CORE (-11)
-#define ARGPARSE_INVALID_ARG (-12)
-
-
-int arg_parse (ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
-int optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
- ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
-void usage (int level);
-const char *strusage (int level);
-void set_strusage (const char *(*f)( int ));
-void argparse_register_outfnc (int (*fnc)(int, const char *));
-
-#endif /*LIBJNLIB_ARGPARSE_H*/
blob - 354c6c96cd8585f1295998368c32087ae336bbf4 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/memory.h
+++ /dev/null
-/* Quintuple Agent secure memory allocation
- * Copyright (C) 1998,1999 Free Software Foundation, Inc.
- * Copyright (C) 1999,2000 Robert Bihlmeyer <robbe@orcus.priv.at>
- *
- * 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 _MEMORY_H
-#define _MEMORY_H
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#if 0
-}
-#endif
-#endif
-
-
-/* values for flags, hardcoded in secmem.c */
-#define SECMEM_WARN 0
-#define SECMEM_DONT_WARN 1
-#define SECMEM_SUSPEND_WARN 2
-
-void secmem_init( size_t npool );
-void secmem_term( void );
-void *secmem_malloc( size_t size );
-void *secmem_realloc( void *a, size_t newsize );
-void secmem_free( void *a );
-int m_is_secure( const void *p );
-void secmem_dump_stats(void);
-void secmem_set_flags( unsigned flags );
-unsigned secmem_get_flags(void);
-size_t secmem_get_max_size (void);
-
-#if 0
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif /* _MEMORY_H */
blob - 898f88cebfc93639fb5050f92ab559956f5f1846 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/password-cache.c
+++ /dev/null
-/* password-cache.c - Password cache support.
- Copyright (C) 2015 g10 Code GmbH
-
- This file is part of PINENTRY.
-
- PINENTRY 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.
-
- PINENTRY 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "../../master.h"
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_LIBSECRET
-# include <libsecret/secret.h>
-#endif
-
-#include "password-cache.h"
-#include "memory.h"
-
-#ifdef HAVE_LIBSECRET
-static const SecretSchema *
-gpg_schema (void)
-{
- static const SecretSchema the_schema = {
- "org.gnupg.Passphrase", SECRET_SCHEMA_NONE,
- {
- { "stored-by", SECRET_SCHEMA_ATTRIBUTE_STRING },
- { "keygrip", SECRET_SCHEMA_ATTRIBUTE_STRING },
- { "NULL", 0 },
- }
- };
- return &the_schema;
-}
-
-static char *
-keygrip_to_label (const char *keygrip)
-{
- char const prefix[] = "GnuPG: ";
- char *label = NULL;
- asprintf (&label, "%s%s", prefix, keygrip);
- return label;
-}
-#endif
-
-void
-password_cache_save (UNUSED const char *keygrip, UNUSED const char *password)
-{
-#ifdef HAVE_LIBSECRET
- char *label;
- GError *error = NULL;
-
- if (! *keygrip)
- return;
-
- label = keygrip_to_label (keygrip);
- if (! label)
- return;
-
- if (! secret_password_store_sync (gpg_schema (),
- SECRET_COLLECTION_DEFAULT,
- label, password, NULL, &error,
- "stored-by", "GnuPG Pinentry",
- "keygrip", keygrip, NULL))
- {
- printf("Failed to cache password for key %s with secret service: %s\n",
- keygrip, error->message);
-
- g_error_free (error);
- }
-
- free (label);
-#else
- return;
-#endif
-}
-
-char *
-password_cache_lookup (UNUSED const char *keygrip)
-{
-#ifdef HAVE_LIBSECRET
- GError *error = NULL;
- char *password;
- char *password2;
- size_t plen;
-
- if (! *keygrip)
- return NULL;
-
- password = secret_password_lookup_nonpageable_sync
- (gpg_schema (), NULL, &error,
- "keygrip", keygrip, NULL);
-
- if (error != NULL)
- {
- printf("Failed to lookup password for key %s with secret service: %s\n",
- keygrip, error->message);
- g_error_free (error);
- return NULL;
- }
- if (! password)
- /* The password for this key is not cached. Just return NULL. */
- return NULL;
-
- /* The password needs to be returned in secmem allocated memory. */
- plen = strlen (password) + 1;
- password2 = secmem_malloc (plen);
- if (password2)
- strlcpy(password2, password, plen);
- else
- printf("secmem_malloc failed: can't copy password!\n");
-
- secret_password_free (password);
-
- return password2;
-#else
- return NULL;
-#endif
-}
-
-/* Try and remove the cached password for key grip. Returns -1 on
- error, 0 if the key is not found and 1 if the password was
- removed. */
-int
-password_cache_clear (UNUSED const char *keygrip)
-{
-#ifdef HAVE_LIBSECRET
- GError *error = NULL;
- int removed = secret_password_clear_sync (gpg_schema (), NULL, &error,
- "keygrip", keygrip, NULL);
- if (error != NULL)
- {
- printf("Failed to clear password for key %s with secret service: %s\n",
- keygrip, error->message);
- g_debug("%s", error->message);
- g_error_free (error);
- return -1;
- }
- if (removed)
- return 1;
- return 0;
-#else
- return -1;
-#endif
-}
blob - 0bc8788f15d28879c4bf63532949397274926b9d (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/password-cache.h
+++ /dev/null
-/* password-cache.h - Password cache support interfaces.
- Copyright (C) 2015 g10 Code GmbH
-
- This file is part of PINENTRY.
-
- PINENTRY 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.
-
- PINENTRY 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PASSWORD_CACHE_H
-#define PASSWORD_CACHE_H
-
-void password_cache_save (const char *key_grip, const char *password);
-
-char *password_cache_lookup (const char *key_grip);
-
-int password_cache_clear (const char *keygrip);
-
-#endif
blob - d10723a94e527940d9188230c4a4feee99a8e97d (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/pinentry.c
+++ /dev/null
-/* pinentry.c - The PIN entry support library
- Copyright (C) 2002, 2003, 2007, 2008, 2010, 2015 g10 Code GmbH
-
- This file is part of PINENTRY.
-
- PINENTRY 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.
-
- PINENTRY 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "../../master.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-
-#include <assuan.h>
-
-#include "memory.h"
-#include "secmem-util.h"
-#include "argparse.h"
-#include "pinentry.h"
-#include "password-cache.h"
-
-/* Keep the name of our program here. */
-static char this_pgmname[50];
-
-struct pinentry pinentry;
-
-static void
-pinentry_reset (int use_defaults)
-{
- /* GPG Agent sets these options once when it starts the pinentry.
- Don't reset them. */
- int grab = pinentry.grab;
- char *ttyname = pinentry.ttyname;
- char *ttytype = pinentry.ttytype;
- char *lc_ctype = pinentry.lc_ctype;
- char *lc_messages = pinentry.lc_messages;
- int allow_external_password_cache = pinentry.allow_external_password_cache;
- char *default_ok = pinentry.default_ok;
- char *default_cancel = pinentry.default_cancel;
- char *default_prompt = pinentry.default_prompt;
- char *default_pwmngr = pinentry.default_pwmngr;
- char *touch_file = pinentry.touch_file;
-
- /* These options are set from the command line. Don't reset
- them. */
- int debug = pinentry.debug;
- char *display = pinentry.display;
- int parent_wid = pinentry.parent_wid;
-
- pinentry_color_t color_fg = pinentry.color_fg;
- int color_fg_bright = pinentry.color_fg_bright;
- pinentry_color_t color_bg = pinentry.color_bg;
- pinentry_color_t color_so = pinentry.color_so;
- int color_so_bright = pinentry.color_so_bright;
-
- int timout = pinentry.timeout;
-
- /* Free any allocated memory. */
- if (use_defaults)
- {
- free (pinentry.ttyname);
- free (pinentry.ttytype);
- free (pinentry.lc_ctype);
- free (pinentry.lc_messages);
- free (pinentry.default_ok);
- free (pinentry.default_cancel);
- free (pinentry.default_prompt);
- free (pinentry.default_pwmngr);
- free (pinentry.touch_file);
- free (pinentry.display);
- }
-
- free (pinentry.title);
- free (pinentry.description);
- free (pinentry.error);
- free (pinentry.prompt);
- free (pinentry.ok);
- free (pinentry.notok);
- free (pinentry.cancel);
- secmem_free (pinentry.pin);
- free (pinentry.repeat_passphrase);
- free (pinentry.repeat_error_string);
- free (pinentry.quality_bar);
- free (pinentry.quality_bar_tt);
- free (pinentry.keyinfo);
-
- /* Reset the pinentry structure. */
- memset (&pinentry, 0, sizeof (pinentry));
-
- if (use_defaults)
- {
- /* Pinentry timeout in seconds. */
- pinentry.timeout = 60;
-
- /* Global grab. */
- pinentry.grab = 1;
-
- pinentry.color_fg = PINENTRY_COLOR_DEFAULT;
- pinentry.color_fg_bright = 0;
- pinentry.color_bg = PINENTRY_COLOR_DEFAULT;
- pinentry.color_so = PINENTRY_COLOR_DEFAULT;
- pinentry.color_so_bright = 0;
- }
- else
- /* Restore the options. */
- {
- pinentry.grab = grab;
- pinentry.ttyname = ttyname;
- pinentry.ttytype = ttytype;
- pinentry.lc_ctype = lc_ctype;
- pinentry.lc_messages = lc_messages;
- pinentry.allow_external_password_cache = allow_external_password_cache;
- pinentry.default_ok = default_ok;
- pinentry.default_cancel = default_cancel;
- pinentry.default_prompt = default_prompt;
- pinentry.default_pwmngr = default_pwmngr;
- pinentry.touch_file = touch_file;
-
- pinentry.debug = debug;
- pinentry.display = display;
- pinentry.parent_wid = parent_wid;
-
- pinentry.color_fg = color_fg;
- pinentry.color_fg_bright = color_fg_bright;
- pinentry.color_bg = color_bg;
- pinentry.color_so = color_so;
- pinentry.color_so_bright = color_so_bright;
-
- pinentry.timeout = timout;
- }
-}
-
-static gpg_error_t
-pinentry_assuan_reset_handler (assuan_context_t ctx, char *line)
-{
- (void)ctx;
- (void)line;
-
- pinentry_reset (0);
-
- return 0;
-}
-
-
-//static int lc_ctype_unknown_warning = 0;
-
-/* Copy TEXT or TEXTLEN to BUFFER and escape as required. Return a
- pointer to the end of the new buffer. Note that BUFFER must be
- large enough to keep the entire text; allocataing it 3 times of
- TEXTLEN is sufficient. */
-static char *
-copy_and_escape (char *buffer, const void *text, size_t textlen)
-{
- int i;
- const unsigned char *s = (unsigned char *)text;
- char *p = buffer;
-
- for (i=0; i < textlen; i++)
- {
- if (s[i] < ' ' || s[i] == '+')
- {
- snprintf (p, 4, "%%%02X", s[i]);
- p += 3;
- }
- else if (s[i] == ' ')
- *p++ = '+';
- else
- *p++ = s[i];
- }
- return p;
-}
-
-
-
-/* Run a quality inquiry for PASSPHRASE of LENGTH. (We need LENGTH
- because not all backends might be able to return a proper
- C-string.). Returns: A value between -100 and 100 to give an
- estimate of the passphrase's quality. Negative values are use if
- the caller won't even accept that passphrase. Note that we expect
- just one data line which should not be escaped in any represent a
- numeric signed decimal value. Extra data is currently ignored but
- should not be send at all. */
-int
-pinentry_inq_quality (pinentry_t pin, const char *passphrase, size_t length)
-{
- assuan_context_t ctx = pin->ctx_assuan;
- const char prefix[] = "INQUIRE QUALITY ";
- char *command;
- char *line;
- size_t linelen, clen;
- int gotvalue = 0;
- int value = 0;
- int rc;
-
- if (!ctx)
- return 0; /* Can't run the callback. */
-
- if (length > 300)
- length = 300; /* Limit so that it definitely fits into an Assuan
- line. */
-
- clen = strlen (prefix) + 3*length + 1;
- command = secmem_malloc (clen);
- if (!command)
- return 0;
- strlcpy (command, prefix, clen);
- copy_and_escape (command + strlen(command), passphrase, length);
- rc = assuan_write_line (ctx, command);
- secmem_free (command);
- if (rc)
- {
- fprintf (stderr, "ASSUAN WRITE LINE failed: rc=%d\n", rc);
- return 0;
- }
-
- for (;;)
- {
- do
- {
- rc = assuan_read_line (ctx, &line, &linelen);
- if (rc)
- {
- fprintf (stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
- return 0;
- }
- }
- while (*line == '#' || !linelen);
- if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
- && (!line[3] || line[3] == ' '))
- break; /* END command received*/
- if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N'
- && (!line[3] || line[3] == ' '))
- break; /* CAN command received*/
- if (line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
- && (!line[3] || line[3] == ' '))
- break; /* ERR command received*/
- if (line[0] != 'D' || line[1] != ' ' || linelen < 3 || gotvalue)
- continue;
- gotvalue = 1;
- value = atoi (line+2);
- }
- if (value < -100)
- value = -100;
- else if (value > 100)
- value = 100;
-
- return value;
-}
-
-
-
-/* Try to make room for at least LEN bytes in the pinentry. Returns
- new buffer on success and 0 on failure or when the old buffer is
- sufficient. */
-char *
-pinentry_setbufferlen (pinentry_t pin, int len)
-{
- char *newp;
-
- if (pin->pin_len)
- assert (pin->pin);
- else
- assert (!pin->pin);
-
- if (len < 2048)
- len = 2048;
-
- if (len <= pin->pin_len)
- return pin->pin;
-
- newp = secmem_realloc (pin->pin, len);
- if (newp)
- {
- pin->pin = newp;
- pin->pin_len = len;
- }
- else
- {
- secmem_free (pin->pin);
- pin->pin = 0;
- pin->pin_len = 0;
- }
- return newp;
-}
-
-static void
-pinentry_setbuffer_clear (pinentry_t pin)
-{
- if (! pin->pin)
- {
- assert (pin->pin_len == 0);
- return;
- }
-
- assert (pin->pin_len > 0);
-
- secmem_free (pin->pin);
- pin->pin = NULL;
- pin->pin_len = 0;
-}
-
-static void
-pinentry_setbuffer_init (pinentry_t pin)
-{
- pinentry_setbuffer_clear (pin);
- pinentry_setbufferlen (pin, 0);
-}
-
-/* passphrase better be alloced with secmem_alloc. */
-void
-pinentry_setbuffer_use (pinentry_t pin, char *passphrase, int len)
-{
- if (! passphrase)
- {
- assert (len == 0);
- pinentry_setbuffer_clear (pin);
-
- return;
- }
-
- if (passphrase && len == 0)
- len = strlen (passphrase) + 1;
-
- if (pin->pin)
- secmem_free (pin->pin);
-
- pin->pin = passphrase;
- pin->pin_len = len;
-}
-
-static struct assuan_malloc_hooks assuan_malloc_hooks = {
- secmem_malloc, secmem_realloc, secmem_free
-};
-
-/* Initialize the secure memory subsystem, drop privileges and return.
- Must be called early. */
-void
-pinentry_init (const char *pgmname)
-{
- /* Store away our name. */
- if (strlen (pgmname) > sizeof this_pgmname - 2)
- abort ();
- strlcpy (this_pgmname, pgmname, sizeof(this_pgmname));
-
- gpgrt_check_version (NULL);
-
- /* Initialize secure memory. 1 is too small, so the default size
- will be used. */
- secmem_init (1);
- secmem_set_flags (SECMEM_WARN);
- drop_privs ();
-
- if (atexit (secmem_term))
- {
- /* FIXME: Could not register at-exit function, bail out. */
- }
-
- assuan_set_malloc_hooks (&assuan_malloc_hooks);
-}
-
-/* Simple test to check whether DISPLAY is set or the option --display
- was given. Used to decide whether the GUI or curses should be
- initialized. */
-int
-pinentry_have_display (int argc, char **argv)
-{
- for (; argc; argc--, argv++)
- if (!strcmp (*argv, "--display") || !strncmp (*argv, "--display=", 10))
- return 1;
- return 0;
-}
-
-
-
-/* Print usage information and and provide strings for help. */
-static const char *
-my_strusage( int level )
-{
- const char *p;
-
- switch (level)
- {
- case 11: p = this_pgmname; break;
- case 12: p = "pinentry"; break;
- case 13: p = VERSION; break;
- case 14: p = "Copyright (C) 2015 g10 Code GmbH"; break;
- case 19: p = "Please report bugs to <" BUGREPORT ">.\n"; break;
- case 1:
- case 40:
- {
- static char *str;
-
- if (!str)
- {
- size_t n = 50 + strlen (this_pgmname);
- str = malloc (n);
- if (str)
- snprintf (str, n, "Usage: %s [options] (-h for help)",
- this_pgmname);
- }
- p = str;
- }
- break;
- case 41:
- p = "Ask securely for a secret and print it to stdout.";
- break;
-
- case 42:
- p = "1"; /* Flag print 40 as part of 41. */
- break;
-
- default: p = NULL; break;
- }
- return p;
-}
-
-
-char *
-parse_color (char *arg, pinentry_color_t *color_p, int *bright_p)
-{
- static struct
- {
- const char *name;
- pinentry_color_t color;
- } colors[] = { { "none", PINENTRY_COLOR_NONE },
- { "default", PINENTRY_COLOR_DEFAULT },
- { "black", PINENTRY_COLOR_BLACK },
- { "red", PINENTRY_COLOR_RED },
- { "green", PINENTRY_COLOR_GREEN },
- { "yellow", PINENTRY_COLOR_YELLOW },
- { "blue", PINENTRY_COLOR_BLUE },
- { "magenta", PINENTRY_COLOR_MAGENTA },
- { "cyan", PINENTRY_COLOR_CYAN },
- { "white", PINENTRY_COLOR_WHITE } };
-
- int i;
- char *new_arg;
- pinentry_color_t color = PINENTRY_COLOR_DEFAULT;
-
- if (!arg)
- return NULL;
-
- new_arg = strchr (arg, ',');
- if (new_arg)
- new_arg++;
-
- if (bright_p)
- {
- const char *bname[] = { "bright-", "bright", "bold-", "bold" };
-
- *bright_p = 0;
- for (i = 0; i < sizeof (bname) / sizeof (bname[0]); i++)
- if (!strncasecmp (arg, bname[i], strlen (bname[i])))
- {
- *bright_p = 1;
- arg += strlen (bname[i]);
- }
- }
-
- for (i = 0; i < sizeof (colors) / sizeof (colors[0]); i++)
- if (!strncasecmp (arg, colors[i].name, strlen (colors[i].name)))
- color = colors[i].color;
-
- *color_p = color;
- return new_arg;
-}
-
-/* Parse the command line options. May exit the program if only help
- or version output is requested. */
-void
-pinentry_parse_opts (int argc, char *argv[])
-{
- static ARGPARSE_OPTS opts[] = {
- ARGPARSE_s_n('d', "debug", "Turn on debugging output"),
- ARGPARSE_s_s('D', "display", "|DISPLAY|Set the X display"),
- ARGPARSE_s_s('T', "ttyname", "|FILE|Set the tty terminal node name"),
- ARGPARSE_s_s('N', "ttytype", "|NAME|Set the tty terminal type"),
- ARGPARSE_s_s('C', "lc-ctype", "|STRING|Set the tty LC_CTYPE value"),
- ARGPARSE_s_s('M', "lc-messages", "|STRING|Set the tty LC_MESSAGES value"),
- ARGPARSE_s_i('o', "timeout",
- "|SECS|Timeout waiting for input after this many seconds"),
- ARGPARSE_s_n('g', "no-global-grab",
- "Grab keyboard only while window is focused"),
- ARGPARSE_s_u('W', "parent-wid", "Parent window ID (for positioning)"),
- ARGPARSE_s_s('c', "colors", "|STRING|Set custom colors for ncurses"),
- ARGPARSE_end()
- };
- ARGPARSE_ARGS pargs;
- memset (&pargs, 0, sizeof (pargs));
- pargs.argc = &argc;
- pargs.argv = &argv;
- pargs.flags = 0;
-
- set_strusage (my_strusage);
-
- pinentry_reset (1);
-
- while (arg_parse (&pargs, opts))
- {
- switch (pargs.r_opt)
- {
- case 'd':
- pinentry.debug = 1;
- break;
- case 'g':
- pinentry.grab = 0;
- break;
-
- case 'D':
- /* Note, this is currently not used because the GUI engine
- has already been initialized when parsing these options. */
- pinentry.display = strdup (pargs.r.ret_str);
- if (!pinentry.display)
- {
- exit (EXIT_FAILURE);
- }
- break;
- case 'T':
- pinentry.ttyname = strdup (pargs.r.ret_str);
- if (!pinentry.ttyname)
- {
- exit (EXIT_FAILURE);
- }
- break;
- case 'N':
- pinentry.ttytype = strdup (pargs.r.ret_str);
- if (!pinentry.ttytype)
- {
- exit (EXIT_FAILURE);
- }
- break;
- case 'C':
- pinentry.lc_ctype = strdup (pargs.r.ret_str);
- if (!pinentry.lc_ctype)
- {
- exit (EXIT_FAILURE);
- }
- break;
- case 'M':
- pinentry.lc_messages = strdup (pargs.r.ret_str);
- if (!pinentry.lc_messages)
- {
- exit (EXIT_FAILURE);
- }
- break;
- case 'W':
- pinentry.parent_wid = pargs.r.ret_ulong;
- break;
-
- case 'c':
- {
- char *tmpstr = pargs.r.ret_str;
-
- tmpstr = parse_color (tmpstr, &pinentry.color_fg,
- &pinentry.color_fg_bright);
- tmpstr = parse_color (tmpstr, &pinentry.color_bg, NULL);
- tmpstr = parse_color (tmpstr, &pinentry.color_so,
- &pinentry.color_so_bright);
- }
- break;
-
- case 'o':
- pinentry.timeout = pargs.r.ret_int;
- break;
-
- default:
- pargs.err = ARGPARSE_PRINT_WARNING;
- break;
- }
- }
-}
-
-
-static gpg_error_t
-option_handler (assuan_context_t ctx, const char *key, const char *value)
-{
- (void)ctx;
-
- if (!strcmp (key, "no-grab") && !*value)
- pinentry.grab = 0;
- else if (!strcmp (key, "grab") && !*value)
- pinentry.grab = 1;
- else if (!strcmp (key, "debug-wait"))
- {
- }
- else if (!strcmp (key, "display"))
- {
- if (pinentry.display)
- free (pinentry.display);
- pinentry.display = strdup (value);
- if (!pinentry.display)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "ttyname"))
- {
- if (pinentry.ttyname)
- free (pinentry.ttyname);
- pinentry.ttyname = strdup (value);
- if (!pinentry.ttyname)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "ttytype"))
- {
- if (pinentry.ttytype)
- free (pinentry.ttytype);
- pinentry.ttytype = strdup (value);
- if (!pinentry.ttytype)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "lc-ctype"))
- {
- if (pinentry.lc_ctype)
- free (pinentry.lc_ctype);
- pinentry.lc_ctype = strdup (value);
- if (!pinentry.lc_ctype)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "lc-messages"))
- {
- if (pinentry.lc_messages)
- free (pinentry.lc_messages);
- pinentry.lc_messages = strdup (value);
- if (!pinentry.lc_messages)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "parent-wid"))
- {
- pinentry.parent_wid = atoi (value);
- /* FIXME: Use strtol and add some error handling. */
- }
- else if (!strcmp (key, "touch-file"))
- {
- if (pinentry.touch_file)
- free (pinentry.touch_file);
- pinentry.touch_file = strdup (value);
- if (!pinentry.touch_file)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "default-ok"))
- {
- pinentry.default_ok = strdup (value);
- if (!pinentry.default_ok)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "default-cancel"))
- {
- pinentry.default_cancel = strdup (value);
- if (!pinentry.default_cancel)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "default-prompt"))
- {
- pinentry.default_prompt = strdup (value);
- if (!pinentry.default_prompt)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "default-pwmngr"))
- {
- pinentry.default_pwmngr = strdup (value);
- if (!pinentry.default_pwmngr)
- return gpg_error_from_syserror ();
- }
- else if (!strcmp (key, "allow-external-password-cache") && !*value)
- {
- pinentry.allow_external_password_cache = 1;
- pinentry.tried_password_cache = 0;
- }
- else if (!strcmp (key, "allow-emacs-prompt") && !*value)
- {
- return gpg_error (GPG_ERR_NOT_SUPPORTED);
- }
- else
- return gpg_error (GPG_ERR_UNKNOWN_OPTION);
- return 0;
-}
-
-
-/* Note, that it is sufficient to allocate the target string D as
- long as the source string S, i.e.: strlen(s)+1; */
-static void
-strcpy_escaped (char *d, const char *s)
-{
- while (*s)
- {
- if (*s == '%' && s[1] && s[2])
- {
- s++;
- *d++ = xtoi_2 ( s);
- s += 2;
- }
- else
- *d++ = *s++;
- }
- *d = 0;
-}
-
-
-static gpg_error_t
-cmd_setdesc (assuan_context_t ctx, char *line)
-{
- char *newd;
-
- (void)ctx;
-
- newd = malloc (strlen (line) + 1);
- if (!newd)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newd, line);
- if (pinentry.description)
- free (pinentry.description);
- pinentry.description = newd;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_setprompt (assuan_context_t ctx, char *line)
-{
- char *newp;
-
- (void)ctx;
-
- newp = malloc (strlen (line) + 1);
- if (!newp)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newp, line);
- if (pinentry.prompt)
- free (pinentry.prompt);
- pinentry.prompt = newp;
- return 0;
-}
-
-
-/* The data provided at LINE may be used by pinentry implementations
- to identify a key for caching strategies of its own. The empty
- string and --clear mean that the key does not have a stable
- identifier. */
-static gpg_error_t
-cmd_setkeyinfo (assuan_context_t ctx, char *line)
-{
- (void)ctx;
-
- if (pinentry.keyinfo)
- free (pinentry.keyinfo);
-
- if (*line && strcmp(line, "--clear") != 0)
- pinentry.keyinfo = strdup (line);
- else
- pinentry.keyinfo = NULL;
-
- return 0;
-}
-
-
-static gpg_error_t
-cmd_setrepeat (assuan_context_t ctx, char *line)
-{
- char *p;
-
- (void)ctx;
-
- p = malloc (strlen (line) + 1);
- if (!p)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (p, line);
- free (pinentry.repeat_passphrase);
- pinentry.repeat_passphrase = p;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_setrepeaterror (assuan_context_t ctx, char *line)
-{
- char *p;
-
- (void)ctx;
-
- p = malloc (strlen (line) + 1);
- if (!p)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (p, line);
- free (pinentry.repeat_error_string);
- pinentry.repeat_error_string = p;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_seterror (assuan_context_t ctx, char *line)
-{
- char *newe;
-
- (void)ctx;
-
- newe = malloc (strlen (line) + 1);
- if (!newe)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newe, line);
- if (pinentry.error)
- free (pinentry.error);
- pinentry.error = newe;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_setok (assuan_context_t ctx, char *line)
-{
- char *newo;
-
- (void)ctx;
-
- newo = malloc (strlen (line) + 1);
- if (!newo)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newo, line);
- if (pinentry.ok)
- free (pinentry.ok);
- pinentry.ok = newo;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_setnotok (assuan_context_t ctx, char *line)
-{
- char *newo;
-
- (void)ctx;
-
- newo = malloc (strlen (line) + 1);
- if (!newo)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newo, line);
- if (pinentry.notok)
- free (pinentry.notok);
- pinentry.notok = newo;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_setcancel (assuan_context_t ctx, char *line)
-{
- char *newc;
-
- (void)ctx;
-
- newc = malloc (strlen (line) + 1);
- if (!newc)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newc, line);
- if (pinentry.cancel)
- free (pinentry.cancel);
- pinentry.cancel = newc;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_settimeout (assuan_context_t ctx, char *line)
-{
- (void)ctx;
-
- if (line && *line)
- pinentry.timeout = atoi (line);
-
- return 0;
-}
-
-static gpg_error_t
-cmd_settitle (assuan_context_t ctx, char *line)
-{
- char *newt;
-
- (void)ctx;
-
- newt = malloc (strlen (line) + 1);
- if (!newt)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newt, line);
- if (pinentry.title)
- free (pinentry.title);
- pinentry.title = newt;
- return 0;
-}
-
-static gpg_error_t
-cmd_setqualitybar (assuan_context_t ctx, char *line)
-{
- char *newval;
-
- (void)ctx;
-
- if (!*line)
- line = "Quality:";
-
- newval = malloc (strlen (line) + 1);
- if (!newval)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newval, line);
- if (pinentry.quality_bar)
- free (pinentry.quality_bar);
- pinentry.quality_bar = newval;
- return 0;
-}
-
-/* Set the tooltip to be used for a quality bar. */
-static gpg_error_t
-cmd_setqualitybar_tt (assuan_context_t ctx, char *line)
-{
- char *newval;
-
- (void)ctx;
-
- if (*line)
- {
- newval = malloc (strlen (line) + 1);
- if (!newval)
- return gpg_error_from_syserror ();
-
- strcpy_escaped (newval, line);
- }
- else
- newval = NULL;
- if (pinentry.quality_bar_tt)
- free (pinentry.quality_bar_tt);
- pinentry.quality_bar_tt = newval;
- return 0;
-}
-
-
-static gpg_error_t
-cmd_getpin (assuan_context_t ctx, char *line)
-{
- int result;
- int set_prompt = 0;
- int just_read_password_from_cache = 0;
-
- (void)line;
-
- pinentry_setbuffer_init (&pinentry);
- if (!pinentry.pin)
- return gpg_error (GPG_ERR_ENOMEM);
-
- /* Try reading from the password cache. */
- if (/* If repeat passphrase is set, then we don't want to read from
- the cache. */
- ! pinentry.repeat_passphrase
- /* Are we allowed to read from the cache? */
- && pinentry.allow_external_password_cache
- && pinentry.keyinfo
- /* Only read from the cache if we haven't already tried it. */
- && ! pinentry.tried_password_cache
- /* If the last read resulted in an error, then don't read from
- the cache. */
- && ! pinentry.error)
- {
- char *password;
-
- pinentry.tried_password_cache = 1;
-
- password = password_cache_lookup (pinentry.keyinfo);
- if (password)
- /* There is a cached password. Try it. */
- {
- int len = strlen(password) + 1;
- if (len > pinentry.pin_len)
- len = pinentry.pin_len;
-
- memcpy (pinentry.pin, password, len);
- pinentry.pin[len] = '\0';
-
- secmem_free (password);
-
- pinentry.pin_from_cache = 1;
-
- assuan_write_status (ctx, "PASSWORD_FROM_CACHE", "");
-
- /* Result is the length of the password not including the
- NUL terminator. */
- result = len - 1;
-
- just_read_password_from_cache = 1;
-
- goto out;
- }
- }
-
- /* The password was not cached (or we are not allowed to / cannot
- use the cache). Prompt the user. */
- pinentry.pin_from_cache = 0;
-
- if (!pinentry.prompt)
- {
- pinentry.prompt = pinentry.default_prompt?pinentry.default_prompt:"PIN:";
- set_prompt = 1;
- }
- pinentry.locale_err = 0;
- pinentry.specific_err = 0;
- pinentry.close_button = 0;
- pinentry.repeat_okay = 0;
- pinentry.one_button = 0;
- pinentry.ctx_assuan = ctx;
- result = (*pinentry_cmd_handler) (&pinentry);
- pinentry.ctx_assuan = NULL;
- if (pinentry.error)
- {
- free (pinentry.error);
- pinentry.error = NULL;
- }
- if (pinentry.repeat_passphrase)
- {
- free (pinentry.repeat_passphrase);
- pinentry.repeat_passphrase = NULL;
- }
- if (set_prompt)
- pinentry.prompt = NULL;
-
- pinentry.quality_bar = 0; /* Reset it after the command. */
-
- if (pinentry.close_button)
- assuan_write_status (ctx, "BUTTON_INFO", "close");
-
- if (result < 0)
- {
- pinentry_setbuffer_clear (&pinentry);
- if (pinentry.specific_err)
- return pinentry.specific_err;
- return (pinentry.locale_err
- ? gpg_error (GPG_ERR_LOCALE_PROBLEM)
- : gpg_error (GPG_ERR_CANCELED));
- }
-
- out:
- if (result)
- {
- if (pinentry.repeat_okay)
- assuan_write_status (ctx, "PIN_REPEATED", "");
- result = assuan_send_data (ctx, pinentry.pin, strlen(pinentry.pin));
- if (!result)
- result = assuan_send_data (ctx, NULL, 0);
-
- if (/* GPG Agent says it's okay. */
- pinentry.allow_external_password_cache && pinentry.keyinfo
- /* We didn't just read it from the cache. */
- && ! just_read_password_from_cache
- /* And the user said it's okay. */
- && pinentry.may_cache_password)
- /* Cache the password. */
- password_cache_save (pinentry.keyinfo, pinentry.pin);
- }
-
- pinentry_setbuffer_clear (&pinentry);
-
- return result;
-}
-
-
-/* Note that the option --one-button is a hack to allow the use of old
- pinentries while the caller is ignoring the result. Given that
- options have never been used or flagged as an error the new option
- is an easy way to enable the messsage mode while not requiring to
- update pinentry or to have the caller test for the message
- command. New applications which are free to require an updated
- pinentry should use MESSAGE instead. */
-static gpg_error_t
-cmd_confirm (assuan_context_t ctx, char *line)
-{
- int result;
-
- pinentry.one_button = !!strstr (line, "--one-button");
- pinentry.quality_bar = 0;
- pinentry.close_button = 0;
- pinentry.locale_err = 0;
- pinentry.specific_err = 0;
- pinentry.canceled = 0;
- pinentry_setbuffer_clear (&pinentry);
- result = (*pinentry_cmd_handler) (&pinentry);
- if (pinentry.error)
- {
- free (pinentry.error);
- pinentry.error = NULL;
- }
-
- if (pinentry.close_button)
- assuan_write_status (ctx, "BUTTON_INFO", "close");
-
- if (result)
- return 0;
-
- if (pinentry.specific_err)
- return pinentry.specific_err;
-
- if (pinentry.locale_err)
- return gpg_error (GPG_ERR_LOCALE_PROBLEM);
-
- if (pinentry.one_button)
- return 0;
-
- if (pinentry.canceled)
- return gpg_error (GPG_ERR_CANCELED);
- return gpg_error (GPG_ERR_NOT_CONFIRMED);
-}
-
-
-static gpg_error_t
-cmd_message (assuan_context_t ctx, char *line)
-{
- (void)line;
-
- return cmd_confirm (ctx, "--one-button");
-}
-
-/* GETINFO <what>
-
- Multipurpose function to return a variety of information.
- Supported values for WHAT are:
-
- version - Return the version of the program.
- pid - Return the process id of the server.
- */
-static gpg_error_t
-cmd_getinfo (assuan_context_t ctx, char *line)
-{
- int rc;
-
- if (!strcmp (line, "version"))
- {
- const char *s = VERSION;
- rc = assuan_send_data (ctx, s, strlen (s));
- }
- else if (!strcmp (line, "pid"))
- {
- char numbuf[50];
-
- snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
- rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
- }
- else
- rc = gpg_error (GPG_ERR_ASS_PARAMETER);
- return rc;
-}
-
-/* CLEARPASSPHRASE <cacheid>
-
- Clear the cache passphrase associated with the key identified by
- cacheid.
- */
-static gpg_error_t
-cmd_clear_passphrase (assuan_context_t ctx, char *line)
-{
- (void)ctx;
-
- if (! line)
- return gpg_error (GPG_ERR_ASS_INV_VALUE);
-
- /* Remove leading and trailing white space. */
- while (*line == ' ')
- line ++;
- while (line[strlen (line) - 1] == ' ')
- line[strlen (line) - 1] = 0;
-
- switch (password_cache_clear (line))
- {
- case 1: return 0;
- case 0: return gpg_error (GPG_ERR_ASS_INV_VALUE);
- default: return gpg_error (GPG_ERR_ASS_GENERAL);
- }
-}
-
-/* Tell the assuan library about our commands. */
-static gpg_error_t
-register_commands (assuan_context_t ctx)
-{
- static struct
- {
- const char *name;
- gpg_error_t (*handler) (assuan_context_t, char *line);
- } table[] =
- {
- { "SETDESC", cmd_setdesc },
- { "SETPROMPT", cmd_setprompt },
- { "SETKEYINFO", cmd_setkeyinfo },
- { "SETREPEAT", cmd_setrepeat },
- { "SETREPEATERROR", cmd_setrepeaterror },
- { "SETERROR", cmd_seterror },
- { "SETOK", cmd_setok },
- { "SETNOTOK", cmd_setnotok },
- { "SETCANCEL", cmd_setcancel },
- { "GETPIN", cmd_getpin },
- { "CONFIRM", cmd_confirm },
- { "MESSAGE", cmd_message },
- { "SETQUALITYBAR", cmd_setqualitybar },
- { "SETQUALITYBAR_TT", cmd_setqualitybar_tt },
- { "GETINFO", cmd_getinfo },
- { "SETTITLE", cmd_settitle },
- { "SETTIMEOUT", cmd_settimeout },
- { "CLEARPASSPHRASE", cmd_clear_passphrase },
- { NULL, NULL }
- };
- int i, j;
- gpg_error_t rc;
-
- for (i = j = 0; table[i].name; i++)
- {
- rc = assuan_register_command (ctx, table[i].name, table[i].handler, NULL);
- if (rc)
- return rc;
- }
- return 0;
-}
-
-
-int
-pinentry_loop2 (int infd, int outfd)
-{
- gpg_error_t rc;
- assuan_fd_t filedes[2];
- assuan_context_t ctx;
-
- /* Extra check to make sure we have dropped privs. */
- if (getuid() != geteuid())
- abort ();
-
- rc = assuan_new (&ctx);
- if (rc)
- {
- fprintf (stderr, "server context creation failed: %s\n",
- gpg_strerror (rc));
- return -1;
- }
-
- /* For now we use a simple pipe based server so that we can work
- from scripts. We will later add options to run as a daemon and
- wait for requests on a Unix domain socket. */
- filedes[0] = assuan_fdopen (infd);
- filedes[1] = assuan_fdopen (outfd);
- rc = assuan_init_pipe_server (ctx, filedes);
- if (rc)
- {
- fprintf (stderr, "%s: failed to initialize the server: %s\n",
- this_pgmname, gpg_strerror (rc));
- return -1;
- }
- rc = register_commands (ctx);
- if (rc)
- {
- fprintf (stderr, "%s: failed to the register commands with Assuan: %s\n",
- this_pgmname, gpg_strerror (rc));
- return -1;
- }
-
- assuan_register_option_handler (ctx, option_handler);
- assuan_register_reset_notify (ctx, pinentry_assuan_reset_handler);
-
- for (;;)
- {
- rc = assuan_accept (ctx);
- if (rc == -1)
- break;
- else if (rc)
- {
- fprintf (stderr, "%s: Assuan accept problem: %s\n",
- this_pgmname, gpg_strerror (rc));
- break;
- }
-
- rc = assuan_process (ctx);
- if (rc)
- {
- fprintf (stderr, "%s: Assuan processing failed: %s\n",
- this_pgmname, gpg_strerror (rc));
- continue;
- }
- }
-
- assuan_release (ctx);
- return 0;
-}
-
-
-/* Start the pinentry event loop. The program will start to process
- Assuan commands until it is finished or an error occurs. If an
- error occurs, -1 is returned. Otherwise, 0 is returned. */
-int
-pinentry_loop (void)
-{
- return pinentry_loop2 (STDIN_FILENO, STDOUT_FILENO);
-}
blob - e154ac5cec9da26363e72be00caa1175a2724a2e (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/pinentry.h
+++ /dev/null
-/* pinentry.h - The interface for the PIN entry support library.
- Copyright (C) 2002, 2003, 2010, 2015 g10 Code GmbH
-
- This file is part of PINENTRY.
-
- PINENTRY 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.
-
- PINENTRY 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PINENTRY_H
-#define PINENTRY_H
-
-#ifdef __cplusplus
-extern "C" {
-#if 0
-}
-#endif
-#endif
-
-typedef enum {
- PINENTRY_COLOR_NONE, PINENTRY_COLOR_DEFAULT,
- PINENTRY_COLOR_BLACK, PINENTRY_COLOR_RED,
- PINENTRY_COLOR_GREEN, PINENTRY_COLOR_YELLOW,
- PINENTRY_COLOR_BLUE, PINENTRY_COLOR_MAGENTA,
- PINENTRY_COLOR_CYAN, PINENTRY_COLOR_WHITE
-} pinentry_color_t;
-
-struct pinentry
-{
- /* The window title, or NULL. (Assuan: "SETTITLE TITLE".) */
- char *title;
- /* The description to display, or NULL. (Assuan: "SETDESC
- DESC".) */
- char *description;
- /* The error message to display, or NULL. (Assuan: "SETERROR
- MESSAGE".) */
- char *error;
- /* The prompt to display, or NULL. (Assuan: "SETPROMPT
- prompt".) */
- char *prompt;
- /* The OK button text to display, or NULL. (Assuan: "SETOK
- OK".) */
- char *ok;
- /* The Not-OK button text to display, or NULL. This is the text for
- the alternative option shown by the third button. (Assuan:
- "SETNOTOK NOTOK".) */
- char *notok;
- /* The Cancel button text to display, or NULL. (Assuan: "SETCANCEL
- CANCEL".) */
- char *cancel;
-
- /* The buffer to store the secret into. */
- char *pin;
- /* The length of the buffer. */
- int pin_len;
- /* Whether the pin was read from an external cache (1) or entered by
- the user (0). */
- int pin_from_cache;
-
- /* The name of the X display to use if X is available and supported.
- (Assuan: "OPTION display DISPLAY".) */
- char *display;
- /* The name of the terminal node to open if X not available or
- supported. (Assuan: "OPTION ttyname TTYNAME".) */
- char *ttyname;
- /* The type of the terminal. (Assuan: "OPTION ttytype TTYTYPE".) */
- char *ttytype;
- /* The LC_CTYPE value for the terminal. (Assuan: "OPTION lc-ctype
- LC_CTYPE".) */
- char *lc_ctype;
- /* The LC_MESSAGES value for the terminal. (Assuan: "OPTION
- lc-messages LC_MESSAGES".) */
- char *lc_messages;
-
- /* True if debug mode is requested. */
- int debug;
-
- /* The number of seconds before giving up while waiting for user input. */
- int timeout;
-
- /* True if caller should grab the keyboard. (Assuan: "OPTION grab"
- or "OPTION no-grab".) */
- int grab;
- /* The window ID of the parent window over which the pinentry window
- should be displayed. (Assuan: "OPTION parent-wid WID".) */
- int parent_wid;
-
- /* The name of an optional file which will be touched after a curses
- entry has been displayed. (Assuan: "OPTION touch-file
- FILENAME".) */
- char *touch_file;
-
- /* The frontend should set this to -1 if the user canceled the
- request, and to the length of the PIN stored in pin
- otherwise. */
- int result;
-
- /* The frontend should set this if the NOTOK button was pressed. */
- int canceled;
-
- /* The frontend should set this to true if an error with the local
- conversion occured. */
- int locale_err;
-
- /* The frontend should set this to a gpg-error so that commands are
- able to return specific error codes. This is an ugly hack due to
- the fact that pinentry_cmd_handler_t returns the length of the
- passphrase or a negative error code. */
- int specific_err;
-
- /* The frontend should set this to true if the window close button
- has been used. This flag is used in addition to a regular return
- value. */
- int close_button;
-
- /* The caller should set this to true if only one button is
- required. This is useful for notification dialogs where only a
- dismiss button is required. */
- int one_button;
-
- /* If true a second prompt for the passphrase is shown and the user
- is expected to enter the same passphrase again. Pinentry checks
- that both match. (Assuan: "SETREPEAT".) */
- char *repeat_passphrase;
-
- /* The string to show if a repeated passphrase does not match.
- (Assuan: "SETREPEATERROR ERROR".) */
- char *repeat_error_string;
-
- /* Set to true if the passphrase has been entered a second time and
- matches the first passphrase. */
- int repeat_okay;
-
- /* If this is not NULL, a passphrase quality indicator is shown.
- There will also be an inquiry back to the caller to get an
- indication of the quality for the passphrase entered so far. The
- string is used as a label for the quality bar. (Assuan:
- "SETQUALITYBAR LABEL".) */
- char *quality_bar;
-
- /* The tooltip to be show for the qualitybar. Malloced or NULL.
- (Assuan: "SETQUALITYBAR_TT TOOLTIP".) */
- char *quality_bar_tt;
-
- /* For the curses pinentry, the color of error messages. */
- pinentry_color_t color_fg;
- int color_fg_bright;
- pinentry_color_t color_bg;
- pinentry_color_t color_so;
- int color_so_bright;
-
- /* Malloced and i18ned default strings or NULL. These strings may
- include an underscore character to indicate an accelerator key.
- A double underscore represents a plain one. */
- /* (Assuan: "OPTION default-ok OK"). */
- char *default_ok;
- /* (Assuan: "OPTION default-cancel CANCEL"). */
- char *default_cancel;
- /* (Assuan: "OPTION default-prompt PROMPT"). */
- char *default_prompt;
- /* (Assuan: "OPTION default-pwmngr
- SAVE_PASSWORD_WITH_PASSWORD_MANAGER?"). */
- char *default_pwmngr;
-
- /* Whether we are allowed to read the password from an external
- cache. (Assuan: "OPTION allow-external-password-cache") */
- int allow_external_password_cache;
-
- /* We only try the cache once. */
- int tried_password_cache;
-
- /* A stable identifier for the key. (Assuan: "SETKEYINFO
- KEYINFO".) */
- char *keyinfo;
-
- /* Whether we may cache the password (according to the user). */
- int may_cache_password;
-
- /* NOTE: If you add any additional fields to this structure, be sure
- to update the initializer in pinentry/pinentry.c!!! */
-
- /* For the quality indicator we need to do an inquiry. Thus we need
- to save the assuan ctx. */
- void *ctx_assuan;
-
-};
-typedef struct pinentry *pinentry_t;
-
-
-/* The pinentry command handler type processes the pinentry request
- PIN. If PIN->pin is zero, request a confirmation, otherwise a PIN
- entry. On confirmation, the function should return TRUE if
- confirmed, and FALSE otherwise. On PIN entry, the function should
- return -1 if an error occured or the user cancelled the operation
- and 1 otherwise. */
-typedef int (*pinentry_cmd_handler_t) (pinentry_t pin);
-
-/* Start the pinentry event loop. The program will start to process
- Assuan commands until it is finished or an error occurs. If an
- error occurs, -1 is returned and errno indicates the type of an
- error. Otherwise, 0 is returned. */
-int pinentry_loop (void);
-
-/* The same as above but allows to specify the i/o descriptors.
- * infd and outfd will be duplicated in this function so the caller
- * still has to close them if necessary.
- */
-int pinentry_loop2 (int infd, int outfd);
-
-
-/* Convert the UTF-8 encoded string TEXT to the encoding given in
- LC_CTYPE. Return NULL on error. */
-char *pinentry_utf8_to_local (const char *lc_ctype, const char *text);
-
-/* Convert TEXT which is encoded according to LC_CTYPE to UTF-8. With
- SECURE set to true, use secure memory for the returned buffer.
- Return NULL on error. */
-char *pinentry_local_to_utf8 (char *lc_ctype, char *text, int secure);
-
-
-/* Run a quality inquiry for PASSPHRASE of LENGTH. */
-int pinentry_inq_quality (pinentry_t pin,
- const char *passphrase, size_t length);
-
-/* Try to make room for at least LEN bytes for the pin in the pinentry
- PIN. Returns new buffer on success and 0 on failure. */
-char *pinentry_setbufferlen (pinentry_t pin, int len);
-
-/* Use the buffer at BUFFER for PIN->PIN. BUFFER must be NULL or
- allocated using secmem_alloc. LEN is the size of the buffer. If
- it is unknown, but BUFFER is a NUL terminated string, you pass 0 to
- just use strlen(buffer)+1. */
-void pinentry_setbuffer_use (pinentry_t pin, char *buffer, int len);
-
-/* Initialize the secure memory subsystem, drop privileges and
- return. Must be called early. */
-void pinentry_init (const char *pgmname);
-
-/* Return true if either DISPLAY is set or ARGV contains the string
- "--display". */
-int pinentry_have_display (int argc, char **argv);
-
-/* Parse the command line options. May exit the program if only help
- or version output is requested. */
-void pinentry_parse_opts (int argc, char *argv[]);
-
-
-/* The caller must define this variable to process assuan commands. */
-extern pinentry_cmd_handler_t pinentry_cmd_handler;
-
-
-
-
-
-#ifdef HAVE_W32_SYSTEM
-/* Windows declares sleep as obsolete, but provides a definition for
- _sleep but non for the still existing sleep. */
-#define sleep(a) _sleep ((a))
-#endif /*HAVE_W32_SYSTEM*/
-
-
-
-#if 0
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PINENTRY_H */
blob - 88a5d45b954d447cc049094dcb1a54f8a405b8ad (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/secmem++.h
+++ /dev/null
-/* STL allocator for secmem
- * Copyright (C) 2008 Marc Mutz <marc@kdab.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 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 <cstddef>
-
-namespace secmem {
-
- template <typename T>
- 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 <typename U>
- struct rebind {
- typedef alloc<U> 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 <typename U> alloc( const alloc<U> & ) {}
- // 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<pointer>( 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 <typename T1,typename T2>
- bool operator==( const alloc<T1> &, const alloc<T2> & ) { return true; }
- template <typename T1, typename T2>
- bool operator!=( const alloc<T1> &, const alloc<T2> & ) { return false; }
-
-}
-
-#endif /* __SECMEM_SECMEMPP_H__ */
blob - b422182b499b577adbf844227b48750ae62d3930 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/secmem-util.h
+++ /dev/null
-/* This file exists because "util.h" is such a generic name that it is
- likely to clash with other such files. */
-#include "util.h"
blob - afe89eee03e79224e5e016f8f5ac59fdfb685c34 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/secmem.c
+++ /dev/null
-/* secmem.c - memory allocation from a secure heap
- * Copyright (C) 1998, 1999, 2003 Free Software Foundation, Inc.
- * Copyright (C) 2015 g10 Code GmbH
- *
- * This file is part of GnuPG.
- *
- * GnuPG 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.
- *
- * GnuPG 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include "../../master.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <unistd.h>
-#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
-# include <sys/mman.h>
-# include <sys/types.h>
-# include <fcntl.h>
-# ifdef USE_CAPABILITIES
-# include <sys/capability.h>
-# endif
-#endif
-#include <string.h>
-
-#include "memory.h"
-
-#ifdef ORIGINAL_GPG_VERSION
-#include "types.h"
-#include "util.h"
-#else /* ORIGINAL_GPG_VERSION */
-
-#include "util.h"
-
-typedef union {
- int a;
- short b;
- char c[1];
- long d;
-#ifdef HAVE_U64_TYPEDEF
- u64 e;
-#endif
- float f;
- double g;
-} PROPERLY_ALIGNED_TYPE;
-
-#define log_error log_info
-#define log_bug log_fatal
-
-void
-log_info(char *template, ...)
-{
- va_list args;
-
- va_start(args, template);
- vfprintf(stderr, template, args);
- va_end(args);
-}
-
-void
-log_fatal(char *template, ...)
-{
- va_list args;
-
- va_start(args, template);
- vfprintf(stderr, template, args);
- va_end(args);
- exit(EXIT_FAILURE);
-}
-
-#endif /* ORIGINAL_GPG_VERSION */
-
-#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
-# define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#define DEFAULT_POOLSIZE 16384
-
-typedef struct memblock_struct MEMBLOCK;
-struct memblock_struct {
- unsigned size;
- union {
- MEMBLOCK *next;
- PROPERLY_ALIGNED_TYPE aligned;
- } u;
-};
-
-
-
-static void *pool;
-static volatile int pool_okay; /* may be checked in an atexit function */
-__attribute__((unused)) static int pool_is_mmapped;
-static size_t poolsize; /* allocated length */
-static size_t poollen; /* used length */
-static MEMBLOCK *unused_blocks;
-static unsigned max_alloced;
-static unsigned cur_alloced;
-static unsigned max_blocks;
-static unsigned cur_blocks;
-static int disable_secmem;
-static int show_warning;
-static int no_warning;
-static int suspend_warning;
-
-
-static void
-print_warn(void)
-{
- if( !no_warning )
- log_info("Warning: using insecure memory!\n");
-}
-
-
-static void
-lock_pool( UNUSED void *p, UNUSED size_t n )
-{
-#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
- int err;
-
- cap_set_proc( cap_from_text("cap_ipc_lock+ep") );
- err = mlock( p, n );
- if( err && errno )
- err = errno;
- cap_set_proc( cap_from_text("cap_ipc_lock+p") );
-
- if( err ) {
- if( errno != EPERM
- #ifdef EAGAIN /* OpenBSD returns this */
- && errno != EAGAIN
- #endif
- )
- log_error("can't lock memory: %s\n", strerror(err));
- show_warning = 1;
- }
-
-#elif defined(HAVE_MLOCK)
- uid_t uid;
- int err;
-
- uid = getuid();
-
-#ifdef HAVE_BROKEN_MLOCK
- if( uid ) {
- errno = EPERM;
- err = errno;
- }
- else {
- err = mlock( p, n );
- if( err && errno )
- err = errno;
- }
-#else
- err = mlock( p, n );
- if( err && errno )
- err = errno;
-#endif
-
- if( uid && !geteuid() ) {
- if( setuid( uid ) || getuid() != geteuid() )
- log_fatal("failed to reset uid: %s\n", strerror(errno));
- }
-
- if( err ) {
- if( errno != EPERM
-#ifdef EAGAIN /* OpenBSD returns this */
- && errno != EAGAIN
-#endif
- )
- log_error("can't lock memory: %s\n", strerror(err));
- show_warning = 1;
- }
-
-#else
- log_info("Please note that you don't have secure memory on this system\n");
-#endif
-}
-
-
-static void
-init_pool( size_t n)
-{
- __attribute__((unused)) size_t pgsize;
-
- poolsize = n;
-
- if( disable_secmem )
- log_bug("secure memory is disabled");
-
-#ifdef HAVE_GETPAGESIZE
- pgsize = getpagesize();
-#else
- pgsize = 4096;
-#endif
-
-#if HAVE_MMAP
- poolsize = (poolsize + pgsize -1 ) & ~(pgsize-1);
-# ifdef MAP_ANONYMOUS
- pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-# else /* map /dev/zero instead */
- { int fd;
-
- fd = open("/dev/zero", O_RDWR);
- if( fd == -1 ) {
- log_error("can't open /dev/zero: %s\n", strerror(errno) );
- pool = (void*)-1;
- }
- else {
- pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
- MAP_PRIVATE, fd, 0);
- close (fd);
- }
- }
-# endif
- if( pool == (void*)-1 )
- log_info("can't mmap pool of %u bytes: %s - using malloc\n",
- (unsigned)poolsize, strerror(errno));
- else {
- pool_is_mmapped = 1;
- pool_okay = 1;
- }
-
-#endif
- if( !pool_okay ) {
- pool = malloc( poolsize );
- if( !pool )
- log_fatal("can't allocate memory pool of %u bytes\n",
- (unsigned)poolsize);
- else
- pool_okay = 1;
- }
- lock_pool( pool, poolsize );
- poollen = 0;
-}
-
-
-/* concatenate unused blocks */
-static void
-compress_pool(void)
-{
- /* fixme: we really should do this */
-}
-
-void
-secmem_set_flags( unsigned flags )
-{
- int was_susp = suspend_warning;
-
- no_warning = flags & 1;
- suspend_warning = flags & 2;
-
- /* and now issue the warning if it is not longer suspended */
- if( was_susp && !suspend_warning && show_warning ) {
- show_warning = 0;
- print_warn();
- }
-}
-
-unsigned
-secmem_get_flags(void)
-{
- unsigned flags;
-
- flags = no_warning ? 1:0;
- flags |= suspend_warning ? 2:0;
- return flags;
-}
-
-void
-secmem_init( size_t n )
-{
- if( !n ) {
-#ifdef USE_CAPABILITIES
- /* drop all capabilities */
- cap_set_proc( cap_from_text("all-eip") );
-
-#elif !defined(HAVE_DOSISH_SYSTEM)
- uid_t uid;
-
- disable_secmem=1;
- uid = getuid();
- if( uid != geteuid() ) {
- if( setuid( uid ) || getuid() != geteuid() )
- log_fatal("failed to drop setuid\n" );
- }
-#endif
- }
- else {
- if( n < DEFAULT_POOLSIZE )
- n = DEFAULT_POOLSIZE;
- if( !pool_okay )
- init_pool(n);
- else
- log_error("Oops, secure memory pool already initialized\n");
- }
-}
-
-
-void *
-secmem_malloc( size_t size )
-{
- MEMBLOCK *mb, *mb2;
- int compressed=0;
-
- if( !pool_okay ) {
- log_info(
- "operation is not possible without initialized secure memory\n");
- log_info("(you may have used the wrong program for this task)\n");
- exit(2);
- }
- if( show_warning && !suspend_warning ) {
- show_warning = 0;
- print_warn();
- }
-
- /* blocks are always a multiple of 32 */
- size += sizeof(MEMBLOCK);
- size = ((size + 31) / 32) * 32;
-
- retry:
- /* try to get it from the used blocks */
- for(mb = unused_blocks,mb2=NULL; mb; mb2=mb, mb = mb->u.next )
- if( mb->size >= size ) {
- if( mb2 )
- mb2->u.next = mb->u.next;
- else
- unused_blocks = mb->u.next;
- goto leave;
- }
- /* allocate a new block */
- if( (poollen + size <= poolsize) ) {
- mb = (void*)((char*)pool + poollen);
- poollen += size;
- mb->size = size;
- }
- else if( !compressed ) {
- compressed=1;
- compress_pool();
- goto retry;
- }
- else
- return NULL;
-
- leave:
- cur_alloced += mb->size;
- cur_blocks++;
- if( cur_alloced > max_alloced )
- max_alloced = cur_alloced;
- if( cur_blocks > max_blocks )
- max_blocks = cur_blocks;
-
- memset (&mb->u.aligned.c, 0,
- size - (size_t) &((struct memblock_struct *) 0)->u.aligned.c);
-
- return &mb->u.aligned.c;
-}
-
-
-void *
-secmem_realloc( void *p, size_t newsize )
-{
- MEMBLOCK *mb;
- size_t size;
- void *a;
-
- if (! p)
- return secmem_malloc(newsize);
-
- mb = (MEMBLOCK*)((char*)p - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
- size = mb->size;
- if( newsize < size )
- return p; /* it is easier not to shrink the memory */
- a = secmem_malloc( newsize );
- memcpy(a, p, size);
- memset((char*)a+size, 0, newsize-size);
- secmem_free(p);
- return a;
-}
-
-
-void
-secmem_free( void *a )
-{
- MEMBLOCK *mb;
- size_t size;
-
- if( !a )
- return;
-
- mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
- size = mb->size;
- /* This does not make much sense: probably this memory is held in the
- * cache. We do it anyway: */
- wipememory2(mb, 0xff, size );
- wipememory2(mb, 0xaa, size );
- wipememory2(mb, 0x55, size );
- wipememory2(mb, 0x00, size );
- mb->size = size;
- mb->u.next = unused_blocks;
- unused_blocks = mb;
- cur_blocks--;
- cur_alloced -= size;
-}
-
-int
-m_is_secure( const void *p )
-{
- return p >= pool && p < (void*)((char*)pool+poolsize);
-}
-
-void
-secmem_term(void)
-{
- if( !pool_okay )
- return;
-
- wipememory2( pool, 0xff, poolsize);
- wipememory2( pool, 0xaa, poolsize);
- wipememory2( pool, 0x55, poolsize);
- wipememory2( pool, 0x00, poolsize);
-#if HAVE_MMAP
- if( pool_is_mmapped )
- munmap( pool, poolsize );
-#endif
- pool = NULL;
- pool_okay = 0;
- poolsize=0;
- poollen=0;
- unused_blocks=NULL;
-}
-
-
-void
-secmem_dump_stats(void)
-{
- if( disable_secmem )
- return;
- fprintf(stderr,
- "secmem usage: %u/%u bytes in %u/%u blocks of pool %lu/%lu\n",
- cur_alloced, max_alloced, cur_blocks, max_blocks,
- (ulong)poollen, (ulong)poolsize );
-}
-
-
-size_t
-secmem_get_max_size (void)
-{
- return poolsize;
-}
blob - feddaf73b09360c488fa7cceec91a62481da3ee3 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/util.c
+++ /dev/null
-/* Quintuple Agent
- * Copyright (C) 1999 Robert Bihlmeyer <robbe@orcus.priv.at>
- *
- * 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define _GNU_SOURCE 1
-
-#include <unistd.h>
-#ifndef HAVE_W32CE_SYSTEM
-# include <errno.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "util.h"
-
-#ifndef HAVE_DOSISH_SYSTEM
-static int uid_set = 0;
-static uid_t real_uid, file_uid;
-#endif /*!HAVE_DOSISH_SYSTEM*/
-
-/* Write DATA of size BYTES to FD, until all is written or an error
- occurs. */
-ssize_t
-xwrite(int fd, const void *data, size_t bytes)
-{
- char *ptr;
- size_t todo;
- ssize_t written = 0;
-
- for (ptr = (char *)data, todo = bytes; todo; ptr += written, todo -= written)
- {
- do
- written = write (fd, ptr, todo);
- while (
-#ifdef HAVE_W32CE_SYSTEM
- 0
-#else
- written == -1 && errno == EINTR
-#endif
- );
- if (written < 0)
- break;
- }
- return written;
-}
-
-#if 0
-extern int debug;
-
-int
-debugmsg(const char *fmt, ...)
-{
- va_list va;
- int ret;
-
- if (debug) {
- va_start(va, fmt);
- fprintf(stderr, "\e[4m");
- ret = vfprintf(stderr, fmt, va);
- fprintf(stderr, "\e[24m");
- va_end(va);
- return ret;
- } else
- return 0;
-}
-#endif
-
-/* initialize uid variables */
-#ifndef HAVE_DOSISH_SYSTEM
-static void
-init_uids(void)
-{
- real_uid = getuid();
- file_uid = geteuid();
- uid_set = 1;
-}
-#endif
-
-
-#if 0 /* Not used. */
-/* lower privileges to the real user's */
-void
-lower_privs()
-{
- if (!uid_set)
- init_uids();
- if (real_uid != file_uid) {
-#ifdef HAVE_SETEUID
- if (seteuid(real_uid) < 0) {
- perror("lowering privileges failed");
- exit(EXIT_FAILURE);
- }
-#else
- fprintf(stderr, _("Warning: running q-agent setuid on this system is dangerous\n"));
-#endif /* HAVE_SETEUID */
- }
-}
-#endif /* if 0 */
-
-#if 0 /* Not used. */
-/* raise privileges to the effective user's */
-void
-raise_privs()
-{
- assert(real_uid >= 0); /* lower_privs() must be called before this */
-#ifdef HAVE_SETEUID
- if (real_uid != file_uid && seteuid(file_uid) < 0) {
- perror("Warning: raising privileges failed");
- }
-#endif /* HAVE_SETEUID */
-}
-#endif /* if 0 */
-
-/* drop all additional privileges */
-void
-drop_privs(void)
-{
-#ifndef HAVE_DOSISH_SYSTEM
- if (!uid_set)
- init_uids();
- if (real_uid != file_uid) {
- if (setuid(real_uid) < 0) {
- perror("dropping privileges failed");
- exit(EXIT_FAILURE);
- }
- file_uid = real_uid;
- }
-#endif
-}
blob - 7986c996c6afd3141c99e14c7d6ef123e7563e3f (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry/util.h
+++ /dev/null
-/* Quintuple Agent utilities
- * Copyright (C) 1999 Robert Bihlmeyer <robbe@orcus.priv.at>
- * Copyright (C) 2003 g10 Code GmbH
- *
- * 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 _UTIL_H
-#define _UTIL_H
-
-#include <sys/types.h>
-
-#ifndef HAVE_BYTE_TYPEDEF
-# undef byte
-# ifdef __riscos__
- /* Norcroft treats char == unsigned char but char* != unsigned char* */
- typedef char byte;
-# else
- typedef unsigned char byte;
-# endif
-# define HAVE_BYTE_TYPEDEF
-#endif
-
-#ifndef HAVE_ULONG_TYPEDEF
-# undef ulong
- typedef unsigned long ulong;
-# define HAVE_ULONG_TYPEDEF
-#endif
-
-
-ssize_t xwrite(int, const void *, size_t); /* write until finished */
-int debugmsg(const char *, ...); /* output a debug message if debugging==on */
-void drop_privs(void); /* finally drop privileges */
-
-
-/* To avoid that a compiler optimizes certain memset calls away, these
- macros may be used instead. */
-#define wipememory2(_ptr,_set,_len) do { \
- volatile char *_vptr=(volatile char *)(_ptr); \
- size_t _vlen=(_len); \
- while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
- } while(0)
-#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
-#define wipe(_ptr,_len) wipememory2(_ptr,0,_len)
-
-
-
-
-#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
- *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
-#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
-
-
-#endif
blob - 8021258ab6391ad9a7bc6394ffbe8cef57401f23 (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry-dmenu.1
+++ /dev/null
-.TH PINENTRY-DMENU 1 "DATE" pinentry-dmenu\-VERSION "pinentry-dmenu Manual"
-
-
-.SH NAME
-pinentry-dmenu - a pinentry program with the charm of dmenu
-.SH DESCRIPTION
-.B pinentry-dmenu
-is a dmenu- and pinentry-based passphrase dialog called from the
-.BR gpg-agent (1)
-daemon. It is not intended to be invoked directly.
-
-
-.SH SYNOPSIS
-Set the
-.B pinentry-program
-in
-.IR ~/.gnupg/gpg-agent.conf
-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 "height =" " 8"
-Height of pinentry-dmenu in pixels (no less than 8)
-.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.
-.TP
-.B Return
-Confirm input
-.TP
-.B Ctrl-Return
-Confirm input
-.TP
-.B Shift\-Return
-Confirm input
-.TP
-.B Escape
-Cancel input
-.TP
-.B C\-c
-Escape
-
-.SS Confirm Mode
-.TP
-.B Down
-Right
-.TP
-.B End
-Right
-.TP
-.B Home
-Left
-.TP
-.B Next
-Right
-.TP
-.B Prior
-Left
-.TP
-.B Up
-Left
-.TP
-.B g
-Cancel input
-.TP
-.B G
-Cancel input
-.TP
-.B h
-Left
-.TP
-.B j
-Left
-.TP
-.B k
-Right
-.TP
-.B l
-Right
-.TP
-.B n
-Confirm with no
-.TP
-.B N
-Confirm with no
-.TP
-.B y
-Confirm with yes
-.TP
-.B Y
-Confirm with yes
-
-.SS Pin Mode
-.TP
-.B End
-Move cursor to the line end
-.TP
-.B Home
-Move cursor to the line begin
-.TP
-.B C\-a
-Home
-.TP
-.B C\-b
-Left
-.TP
-.B C\-d
-Delete
-.TP
-.B C\-e
-End
-.TP
-.B C\-f
-Right
-.TP
-.B C\-g
-Escape
-.TP
-.B C\-h
-Backspace
-.TP
-.B C\-k
-Delete line right
-.TP
-.B C\-u
-Delete line left
-.TP
-.B C\-v
-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
-.B dmenu
-<https://tools.suckless.org/dmenu>
-and uses the api of
-.B pinentry
-, a GnuPG tool.
-.B pinentry-dmenu
-itself was written by Moritz Lüdecke <ritze@skweez.net>.
-This version of pinentry-dmenu is a part of Benjamin Stürz' custom desktop.
-
-
-.SH REPORTING BUGS
-Report pinentry-dmenu bugs to Benjamin Stürz <benni@stuerz.xyz>.
-
-
-.SH SEE ALSO
-.BR dmenu (1),
-.BR dwm (1),
-.BR gpg-agent (1)
blob - 0c57ceed3e49bb04802d54b7741a2252d85a1b3f (mode 644)
blob + /dev/null
--- pinentry-dmenu/pinentry-dmenu.c
+++ /dev/null
-/* See LICENSE file for copyright and license details. */
-#include <ctype.h>
-#include <locale.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <pwd.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <X11/Xutil.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-#include <X11/Xft/Xft.h>
-
-#include "drw.h"
-#include "util.h"
-
-#include "pinentry/pinentry.h"
-#include "pinentry/memory.h"
-
-#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 TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
-#define MINDESCLEN 8
-
-
-enum { SchemePrompt, SchemeNormal, SchemeSelect, SchemeDesc, SchemeLast };
-enum { WinPin, WinConfirm };
-enum { Ok, NotOk, Cancel };
-enum { Nothing, Yes, No };
-
-static int bh, mw, mh;
-static int sel;
-static int promptw, pdescw;
-/* Sum of left and right padding */
-static int lrpad;
-static size_t cursor;
-static int screen;
-
-static char* pin;
-static int pin_len;
-static char* pin_repeat;
-static int pin_repeat_len;
-static int repeat;
-
-static Atom clip, utf8;
-static Display *dpy;
-static Window root, parentwin, win;
-static XIC xic;
-
-static Drw *drw;
-static Clr *scheme[SchemeLast];
-
-static int timed_out;
-static int winmode;
-pinentry_t pinentry_info;
-
-#include "config.h"
-
-static int
-drawitem(const char* text, Bool sel, int x, int y, int w) {
- unsigned int i = (sel) ? SchemeSelect : SchemeNormal;
-
- drw_setscheme(drw, scheme[i]);
-
- return drw_text(drw, x, y, w, bh, lrpad / 2, text, 0);
-}
-
-static void
-grabfocus(void) {
- Window focuswin;
- int i, revertwin;
-
- for (i = 0; i < 100; ++i) {
- XGetInputFocus(dpy, &focuswin, &revertwin);
- if (focuswin == win) {
- return;
- }
- XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
- usleep(1000);
- }
-
- die("cannot grab focus");
-}
-
-static void
-grabkeyboard(void) {
- int i;
-
- if (embedded) {
- return;
- }
-
- /* 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) {
- return;
- }
- usleep(1000);
- }
-
- die("cannot grab keyboard");
-}
-
-static size_t
-nextrune(int cursor, 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 n;
-}
-
-static void
-setup_pin(char* pin_ptr, int len, int reset) {
- pin = pin_ptr;
- pin_len = len;
-
- if (reset) {
- promptw = (prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
- cursor = 0;
-
- if (pin) {
- pin[0] = '\0';
- }
- }
-}
-
-static void
-insert(const char *str, ssize_t n) {
- size_t len = strlen(pin);
-
- // FIXME: Pinentry crashes when increasing the pin buffer the second time.
- // Other pinentry programs has a limited passwort field length.
- if (len + n > pin_len - 1) {
- if (repeat) {
- 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) {
- pin_len = 0;
- }
- } else {
- if (!pinentry_setbufferlen(pinentry_info, 2 * pinentry_info->pin_len)) {
- pin_len = 0;
- } else {
- setup_pin(pinentry_info->pin, pinentry_info->pin_len, 0);
- }
- }
- if (pin_len == 0) {
- printf("Error: Couldn't allocate secure memory\n");
- return;
- }
- }
-
- /* 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) {
- memcpy(&pin[cursor], str, n);
- }
-
- cursor += n;
- pin[len + n] = '\0';
-}
-
-static void
-drawwin(void) {
- unsigned int curpos;
- int x = 0, fh = drw->fonts->h, pb, pbw = 0, i;
- size_t asterlen = strlen(asterisk);
- size_t pdesclen;
- int leftinput;
- char* censort;
-
- char* pprompt = (repeat) ? pinentry_info->repeat_passphrase : pinentry_info->prompt;
- int ppromptw = (pprompt) ? TEXTW(pprompt) : 0;
-
- unsigned int censortl = minpwlen * TEXTW(asterisk) / strlen(asterisk);
- unsigned int confirml = TEXTW(" YesNo ") + 3 * lrpad;
-
- drw_setscheme(drw, scheme[SchemeNormal]);
- drw_rect(drw, 0, 0, mw, mh, 1, 1);
-
- if (prompt) {
- drw_setscheme(drw, scheme[SchemePrompt]);
- x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0);
- }
-
- if (pprompt) {
- drw_setscheme(drw, scheme[SchemePrompt]);
- drw_text(drw, x, 0, ppromptw, bh, lrpad / 2, pprompt, 0);
- x += ppromptw;
- }
-
- if (pinentry_info->description) {
- pb = mw - x;
- pdesclen = strlen(pinentry_info->description);
-
- if (pb > 0) {
- pb -= (winmode == WinPin) ? censortl : confirml;
- pbw = MINDESCLEN * pdescw / pdesclen;
- pbw = MIN(pbw, pdescw);
-
- if (pb >= pbw) {
- pbw = MAX(pbw, pdescw);
- pbw = MIN(pbw, pb);
- pb = mw - pbw;
-
- 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,
- 0);
- } else {
- pbw = 0;
- }
- }
- }
-
- /* Draw input field */
- drw_setscheme(drw, scheme[SchemeNormal]);
-
- if (winmode == WinPin) {
- censort = ecalloc(1, asterlen * pin_len);
-
- 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);
-
- if ((curpos += lrpad / 2 - 1) < leftinput) {
- drw_setscheme(drw, scheme[SchemeNormal]);
- drw_rect(drw, x + curpos, 2 + (bh - fh) / 2, 2, fh - 4, 1, 0);
- }
-
- free(censort);
- } else {
- x += TEXTW(" ");
- 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;
- unsigned int du;
- XSetWindowAttributes swa;
- XIM xim;
- Window w, dw, *dws;
- XWindowAttributes wa;
-#ifdef XINERAMA
- XineramaScreenInfo *info;
- Window pw;
- int a, j, 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);
-
- clip = XInternAtom(dpy, "CLIPBOARD", False);
- utf8 = XInternAtom(dpy, "UTF8_STRING", False);
-
- /* Calculate menu geometry */
- bh = drw->fonts->h + 2;
- bh = MAX(bh, lineheight);
- mh = bh;
-#ifdef XINERAMA
- info = XineramaQueryScreens(dpy, &n);
-
- if (parentwin == root && info) {
- XGetInputFocus(dpy, &w, &di);
- if (mon >= 0 && mon < n) {
- i = mon;
- } 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) {
- 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) {
- 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])) {
- break;
- }
- }
- }
-
- x = info[i].x_org;
- y = info[i].y_org + (bottom ? info[i].height - mh : 0);
- mw = info[i].width;
- XFree(info);
- } else
-#endif
- {
- if (!XGetWindowAttributes(dpy, parentwin, &wa)) {
- die("could not get embedding window attributes: 0x%lx", parentwin);
- }
- x = 0;
- y = bottom ? wa.height - mh : 0;
- mw = wa.width;
- }
-
- pdescw = (pinentry_info->description) ? TEXTW(pinentry_info->description) : 0;
-
- /* Create menu window */
- swa.override_redirect = True;
- swa.background_pixel = scheme[SchemePrompt][ColBg].pixel;
- swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
- CopyFromParent, CopyFromParent, CopyFromParent,
- CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
-
- /* 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 (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
- 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) {
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- free(scheme[SchemeDesc]);
- free(scheme[SchemeSelect]);
- free(scheme[SchemeNormal]);
- free(scheme[SchemePrompt]);
- drw_free(drw);
- XSync(dpy, False);
- XCloseDisplay(dpy);
-}
-
-static int
-keypress_confirm(XKeyEvent *ev, KeySym ksym) {
- if (ev->state & ControlMask) {
- switch(ksym) {
- case XK_c:
- pinentry_info->canceled = 1;
- sel = No;
- return 1;
- default:
- return 1;
- }
- }
-
- switch(ksym) {
- case XK_KP_Enter:
- case XK_Return:
- if (sel != Nothing) {
- return 1;
- }
- break;
- case XK_y:
- case XK_Y:
- sel = Yes;
- return 1;
- case XK_n:
- case XK_N:
- sel = No;
- return 1;
- case XK_g:
- case XK_G:
- case XK_Escape:
- pinentry_info->canceled = 1;
- sel = No;
- return 1;
- case XK_h:
- case XK_j:
- case XK_Home:
- case XK_Left:
- case XK_Prior:
- case XK_Up:
- sel = No;
- break;
- case XK_k:
- case XK_l:
- case XK_Down:
- case XK_End:
- case XK_Next:
- case XK_Right:
- sel = Yes;
- break;
- }
-
- return 0;
-}
-
-static int
-keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) {
- int old;
-
- if (ev->state & ControlMask) {
- switch(ksym) {
- case XK_a: ksym = XK_Home; break;
- case XK_b: ksym = XK_Left; break;
- case XK_c: ksym = XK_Escape; break;
- case XK_d: ksym = XK_Delete; break;
- case XK_e: ksym = XK_End; break;
- case XK_f: ksym = XK_Right; break;
- case XK_g: ksym = XK_Escape; break;
- case XK_h: ksym = XK_BackSpace; break;
- case XK_k:
- old = cursor;
- cursor = strlen(pin);
- insert(NULL, old - cursor);
- break;
- case XK_u:
- insert(NULL, -cursor);
- break;
- case XK_v:
- XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
- utf8, utf8, win, CurrentTime);
- return 0;
- case XK_Return:
- case XK_KP_Enter:
- break;
- case XK_bracketleft:
- pinentry_info->canceled = 1;
- return 1;
- default:
- return 1;
- }
- }
-
- switch(ksym) {
- case XK_Delete:
- if (pin[cursor] == '\0') {
- return 0;
- }
- cursor = nextrune(cursor, +1);
- /* Fallthrough */
- case XK_BackSpace:
- if (cursor == 0) {
- return 0;
- }
- insert(NULL, nextrune(cursor, -1) - cursor);
- break;
- case XK_Escape:
- pinentry_info->canceled = 1;
- return 1;
- case XK_Left:
- if (cursor > 0) {
- cursor = nextrune(cursor, -1);
- }
- break;
- case XK_Right:
- if (pin[cursor] != '\0') {
- cursor = nextrune(cursor, +1);
- }
- break;
- case XK_Home:
- cursor = 0;
- break;
- case XK_End:
- cursor = strlen(pin);
- break;
- case XK_Return:
- case XK_KP_Enter:
- return 1;
- break;
- default:
- if (!iscntrl(*buf)) {
- insert(buf, len);
- }
- }
-
- return 0;
-}
-
-static int
-keypress(XKeyEvent *ev) {
- char buf[32];
- int len;
- int ret = 1;
-
- KeySym ksym = NoSymbol;
- Status status;
- len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status);
-
- if (status != XBufferOverflow) {
- if (winmode == WinConfirm) {
- ret = keypress_confirm(ev, ksym);
- } else {
- ret = keypress_pin(ev, ksym, buf, len);
- }
-
- if (ret == 0) {
- drawwin();
- }
- }
-
- return ret;
-}
-
-static 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();
-}
-
-void
-run(void) {
- XEvent ev;
-
- drawwin();
-
- while (!XNextEvent(dpy, &ev)) {
- if (XFilterEvent(&ev, win)) {
- continue;
- }
- switch(ev.type) {
- case Expose:
- if (ev.xexpose.count == 0) {
- drw_map(drw, win, 0, 0, mw, mh);
- }
- break;
- case KeyPress:
- if (keypress(&ev.xkey)) {
- return;
- }
- break;
- case SelectionNotify:
- if (ev.xselection.property == utf8) {
- paste();
- }
- break;
- case VisibilityNotify:
- if (ev.xvisibility.state != VisibilityUnobscured) {
- XRaiseWindow(dpy, win);
- }
- break;
- }
- }
-}
-
-static void
-catchsig(int sig) {
- if (sig == SIGALRM) {
- timed_out = 1;
- }
-}
-
-static void
-password(void) {
- winmode = WinPin;
- repeat = 0;
- setup_pin(pinentry_info->pin, pinentry_info->pin_len, 1);
- run();
-
- if (!pinentry_info->canceled && pinentry_info->repeat_passphrase) {
- repeat = 1;
- pin_repeat_len = pinentry_info->pin_len;
- pin_repeat = secmem_malloc(pinentry_info->pin_len);
- setup_pin(pin_repeat, pin_repeat_len, 1);
- run();
-
- pinentry_info->repeat_okay = (strcmp(pinentry_info->pin, pin_repeat) == 0)? 1 : 0;
- secmem_free(pin_repeat);
-
- if (!pinentry_info->repeat_okay) {
- pinentry_info->result = -1;
- return;
- }
- }
-
- if (pinentry_info->canceled) {
- pinentry_info->result = -1;
- return;
- }
-
- pinentry_info->result = strlen(pinentry_info->pin);
-}
-
-static void
-confirm(void) {
- winmode = WinConfirm;
- sel = Nothing;
- run();
- pinentry_info->result = sel != No;
-}
-
-static int
-cmdhandler(pinentry_t received_pinentry) {
- struct sigaction sa;
- XWindowAttributes wa;
-
- pinentry_info = received_pinentry;
-
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) {
- fputs("warning: no locale support\n", stderr);
- }
- 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)) {
- 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))) {
- die("no fonts could be loaded.");
- }
- lrpad = drw->fonts->h;
- drw_setscheme(drw, scheme[SchemePrompt]);
-
- if (pinentry_info->timeout) {
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = catchsig;
- sigaction(SIGALRM, &sa, NULL);
- alarm(pinentry_info->timeout);
- }
-
- grabkeyboard();
- setup();
-
- if (pinentry_info->pin) {
- do {
- password();
- } while (!pinentry_info->canceled && pinentry_info->repeat_passphrase
- && !pinentry_info->repeat_okay);
- } else {
- confirm();
- }
-
- cleanup();
-
- return pinentry_info->result;
-}
-
-pinentry_cmd_handler_t pinentry_cmd_handler = cmdhandler;
-
-int
-main(int argc, char *argv[]) {
- pinentry_init("pinentry-dmenu");
- pinentry_parse_opts(argc, argv);
- return pinentry_loop();
-}
blob - fe044fc7b7978d1f3c23768e315aae415d90b11a (mode 644)
blob + /dev/null
--- pinentry-dmenu/util.c
+++ /dev/null
-/* See LICENSE file for copyright and license details. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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, ...) {
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
- fputc(' ', stderr);
- perror(NULL);
- } else {
- fputc('\n', stderr);
- }
-
- exit(1);
-}
blob - f633b5173ad2b5058d48574d5a18fe3f135c4193 (mode 644)
blob + /dev/null
--- pinentry-dmenu/util.h
+++ /dev/null
-/* See LICENSE file for copyright and license details. */
-
-#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))
-
-void die(const char *fmt, ...);
-void *ecalloc(size_t nmemb, size_t size);