Author esrever_otua
Recipients
Date 2005-07-12.00:56:56
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
Logged In: YES 
user_id=567623

Following on from earlier code; the code below implements a
complete C module for Python that provides a 'getpass'
implementation for windows that behaves similarly to
existing getpass (accepts a prompt, returns a string without
newlines).  I'm not a fantastic C coder, so this is really
just to provide ideas.


/*
 * This file is part of 'win32console'
 * Copyright 2005 Darryl A. Dixon
<esrever_otua@pythonhacker.is-a-geek.net>
 */
#include <string.h>
#include <windows.h>
#include "Python.h"

#define LINE_BUF 1024 * sizeof(TCHAR)
#define CHAR_BUF 6 * sizeof(TCHAR)

/* Module globals */
static PyObject *getpass_error = NULL;

static PyObject *getpass(self, args)
    PyObject *self, *args;
{
    char *prompt = "Password: ";
    char *newline = "\r\n";
    if (PyArg_ParseTuple(args, "|s", &prompt)){
        HANDLE hstdin, hstdout;
        DWORD read_chars, mode, written_chars;
        char inchars[LINE_BUF];
        hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
        WriteConsole(hstdout,
                     prompt,
                     strlen(prompt),
                     &written_chars,
                     NULL);
        hstdin = GetStdHandle(STD_INPUT_HANDLE);
        GetConsoleMode(hstdin,
                       &mode);
        SetConsoleMode(hstdin,
                       ENABLE_LINE_INPUT |
ENABLE_PROCESSED_INPUT);
        /* Hmm, is allowing threads to run while we're
playing with the flags on
         * STDIN such a good idea?  ...Who knows... */
        Py_BEGIN_ALLOW_THREADS
        ReadConsole(hstdin,
                    inchars,
                    LINE_BUF,
                    &read_chars,
                    NULL);
        Py_END_ALLOW_THREADS
        SetConsoleMode(hstdin,
                       mode);
        WriteConsole(hstdout,
                     newline,
                     strlen(newline),
                     &written_chars,
                     NULL);
        /* -2 to strip the \015\012 from the end
-------------v */
        return PyString_FromStringAndSize(inchars,
read_chars-2);
    }else{
        return NULL;
    }
}

static PyObject *getch(self, args)
        PyObject *self, *args;
{
    if (PyArg_ParseTuple(args, "")){
        HANDLE hstdin;
        DWORD read_chars, mode;
        char inchars[CHAR_BUF];
        hstdin = GetStdHandle(STD_INPUT_HANDLE);
        GetConsoleMode(hstdin,
                       &mode);
        SetConsoleMode(hstdin,
                       ENABLE_PROCESSED_INPUT);
        Py_BEGIN_ALLOW_THREADS
        ReadConsole(hstdin,
                    inchars,
                    CHAR_BUF,
                    &read_chars,
                    NULL);
        Py_END_ALLOW_THREADS
        SetConsoleMode(hstdin,
                       mode);
        /* this should generally always be 1 ----------v */
        return PyString_FromStringAndSize(inchars, read_chars);
    }else{
        return NULL;
    }
}

static PyMethodDef methods[] = {
  {"getpass", getpass, METH_VARARGS},
  {"getch", getch, METH_VARARGS},
  {NULL, NULL},
};

void init_win32console(){
    PyObject *mod, *dict;

    mod = Py_InitModule("_win32console", methods);
    dict = PyModule_GetDict(mod);

#if PYTHON_API_VERSION >= 1007
    getpass_error = PyErr_NewException("getpass.error",
NULL, NULL);
#else
    getpass_error = Py_BuildValue("s", "getpass.error");
#endif
    PyDict_SetItemString(dict, "error", getpass_error);
}
History
Date User Action Args
2008-01-20 09:57:58adminlinkissue1233785 messages
2008-01-20 09:57:58admincreate