diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-2.6.1/Demo/pysvr/pysvr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/python-2.6.1/Demo/pysvr/pysvr.c Fri Jul 31 15:01:17 2009 +0100 @@ -0,0 +1,370 @@ +/* A multi-threaded telnet-like server that gives a Python prompt. + +Usage: pysvr [port] + +For security reasons, it only accepts requests from the current host. +This can still be insecure, but restricts violations from people who +can log in on your machine. Use with caution! + +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +/* XXX Umpfh. + Python.h defines a typedef destructor, which conflicts with pthread.h. + So Python.h must be included after pthread.h. */ + +#include "Python.h" + +extern int Py_VerboseFlag; + +#ifndef PORT +#define PORT 4000 +#endif + +struct workorder { + int conn; + struct sockaddr_in addr; +}; + +/* Forward */ +static void init_python(void); +static void usage(void); +static void oprogname(void); +static void main_thread(int); +static void create_thread(int, struct sockaddr_in *); +static void *service_thread(struct workorder *); +static void run_interpreter(FILE *, FILE *); +static int run_command(char *, PyObject *); +static void ps(void); + +static char *progname = "pysvr"; + +static PyThreadState *gtstate; + +main(int argc, char **argv) +{ + int port = PORT; + int c; + + if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0') + progname = argv[0]; + + while ((c = getopt(argc, argv, "v")) != EOF) { + switch (c) { + case 'v': + Py_VerboseFlag++; + break; + default: + usage(); + } + } + + if (optind < argc) { + if (optind+1 < argc) { + oprogname(); + fprintf(stderr, "too many arguments\n"); + usage(); + } + port = atoi(argv[optind]); + if (port <= 0) { + fprintf(stderr, "bad port (%s)\n", argv[optind]); + usage(); + } + } + + main_thread(port); + + fprintf(stderr, "Bye.\n"); + + exit(0); +} + +static char usage_line[] = "usage: %s [port]\n"; + +static void +usage(void) +{ + fprintf(stderr, usage_line, progname); + exit(2); +} + +static void +main_thread(int port) +{ + int sock, conn, size, i; + struct sockaddr_in addr, clientaddr; + + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + oprogname(); + perror("can't create socket"); + exit(1); + } + +#ifdef SO_REUSEADDR + i = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof i); +#endif + + memset((char *)&addr, '\0', sizeof addr); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = 0L; + if (bind(sock, (struct sockaddr *)&addr, sizeof addr) < 0) { + oprogname(); + perror("can't bind socket to address"); + exit(1); + } + + if (listen(sock, 5) < 0) { + oprogname(); + perror("can't listen on socket"); + exit(1); + } + + fprintf(stderr, "Listening on port %d...\n", port); + + for (i = 0; ; i++) { + size = sizeof clientaddr; + memset((char *) &clientaddr, '\0', size); + conn = accept(sock, (struct sockaddr *) &clientaddr, &size); + if (conn < 0) { + oprogname(); + perror("can't accept connection from socket"); + exit(1); + } + + size = sizeof addr; + memset((char *) &addr, '\0', size); + if (getsockname(conn, (struct sockaddr *)&addr, &size) < 0) { + oprogname(); + perror("can't get socket name of connection"); + exit(1); + } + if (clientaddr.sin_addr.s_addr != addr.sin_addr.s_addr) { + oprogname(); + perror("connection from non-local host refused"); + fprintf(stderr, "(addr=%lx, clientaddr=%lx)\n", + ntohl(addr.sin_addr.s_addr), + ntohl(clientaddr.sin_addr.s_addr)); + close(conn); + continue; + } + if (i == 4) { + close(conn); + break; + } + create_thread(conn, &clientaddr); + } + + close(sock); + + if (gtstate) { + PyEval_AcquireThread(gtstate); + gtstate = NULL; + Py_Finalize(); + /* And a second time, just because we can. */ + Py_Finalize(); /* This should be harmless. */ + } + exit(0); +} + +static void +create_thread(int conn, struct sockaddr_in *addr) +{ + struct workorder *work; + pthread_t tdata; + + work = malloc(sizeof(struct workorder)); + if (work == NULL) { + oprogname(); + fprintf(stderr, "out of memory for thread.\n"); + close(conn); + return; + } + work->conn = conn; + work->addr = *addr; + + init_python(); + + if (pthread_create(&tdata, NULL, (void *)service_thread, work) < 0) { + oprogname(); + perror("can't create new thread"); + close(conn); + return; + } + + if (pthread_detach(tdata) < 0) { + oprogname(); + perror("can't detach from thread"); + } +} + +static PyThreadState *the_tstate; +static PyInterpreterState *the_interp; +static PyObject *the_builtins; + +static void +init_python(void) +{ + if (gtstate) + return; + Py_Initialize(); /* Initialize the interpreter */ + PyEval_InitThreads(); /* Create (and acquire) the interpreter lock */ + gtstate = PyEval_SaveThread(); /* Release the thread state */ +} + +static void * +service_thread(struct workorder *work) +{ + FILE *input, *output; + + fprintf(stderr, "Start thread for connection %d.\n", work->conn); + + ps(); + + input = fdopen(work->conn, "r"); + if (input == NULL) { + oprogname(); + perror("can't create input stream"); + goto done; + } + + output = fdopen(work->conn, "w"); + if (output == NULL) { + oprogname(); + perror("can't create output stream"); + fclose(input); + goto done; + } + + setvbuf(input, NULL, _IONBF, 0); + setvbuf(output, NULL, _IONBF, 0); + + run_interpreter(input, output); + + fclose(input); + fclose(output); + + done: + fprintf(stderr, "End thread for connection %d.\n", work->conn); + close(work->conn); + free(work); +} + +static void +oprogname(void) +{ + int save = errno; + fprintf(stderr, "%s: ", progname); + errno = save; +} + +static void +run_interpreter(FILE *input, FILE *output) +{ + PyThreadState *tstate; + PyObject *new_stdin, *new_stdout; + PyObject *mainmod, *globals; + char buffer[1000]; + char *p, *q; + int n, end; + + PyEval_AcquireLock(); + tstate = Py_NewInterpreter(); + if (tstate == NULL) { + fprintf(output, "Sorry -- can't create an interpreter\n"); + return; + } + + mainmod = PyImport_AddModule("__main__"); + globals = PyModule_GetDict(mainmod); + Py_INCREF(globals); + + new_stdin = PyFile_FromFile(input, "", "r", NULL); + new_stdout = PyFile_FromFile(output, "", "w", NULL); + + PySys_SetObject("stdin", new_stdin); + PySys_SetObject("stdout", new_stdout); + PySys_SetObject("stderr", new_stdout); + + for (n = 1; !PyErr_Occurred(); n++) { + Py_BEGIN_ALLOW_THREADS + fprintf(output, "%d> ", n); + p = fgets(buffer, sizeof buffer, input); + Py_END_ALLOW_THREADS + + if (p == NULL) + break; + if (p[0] == '\377' && p[1] == '\354') + break; + + q = strrchr(p, '\r'); + if (q && q[1] == '\n' && q[2] == '\0') { + *q++ = '\n'; + *q++ = '\0'; + } + + while (*p && isspace(*p)) + p++; + if (p[0] == '#' || p[0] == '\0') + continue; + + end = run_command(buffer, globals); + if (end < 0) + PyErr_Print(); + + if (end) + break; + } + + Py_XDECREF(globals); + Py_XDECREF(new_stdin); + Py_XDECREF(new_stdout); + + Py_EndInterpreter(tstate); + PyEval_ReleaseLock(); + + fprintf(output, "Goodbye!\n"); +} + +static int +run_command(char *buffer, PyObject *globals) +{ + PyObject *m, *d, *v; + fprintf(stderr, "run_command: %s", buffer); + if (strchr(buffer, '\n') == NULL) + fprintf(stderr, "\n"); + v = PyRun_String(buffer, Py_single_input, globals, globals); + if (v == NULL) { + if (PyErr_Occurred() == PyExc_SystemExit) { + PyErr_Clear(); + return 1; + } + PyErr_Print(); + return 0; + } + Py_DECREF(v); + return 0; +} + +static void +ps(void) +{ + char buffer[100]; + PyOS_snprintf(buffer, sizeof(buffer), + "ps -l -p %d