~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to Demo/pysvr/pysvr.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#endif
35
35
 
36
36
struct workorder {
37
 
        int conn;
38
 
        struct sockaddr_in addr;
 
37
    int conn;
 
38
    struct sockaddr_in addr;
39
39
};
40
40
 
41
41
/* Forward */
55
55
 
56
56
main(int argc, char **argv)
57
57
{
58
 
        int port = PORT;
59
 
        int c;
60
 
 
61
 
        if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0')
62
 
                progname = argv[0];
63
 
 
64
 
        while ((c = getopt(argc, argv, "v")) != EOF) {
65
 
                switch (c) {
66
 
                case 'v':
67
 
                        Py_VerboseFlag++;
68
 
                        break;
69
 
                default:
70
 
                        usage();
71
 
                }
72
 
        }
73
 
 
74
 
        if (optind < argc) {
75
 
                if (optind+1 < argc) {
76
 
                        oprogname();
77
 
                        fprintf(stderr, "too many arguments\n");
78
 
                        usage();
79
 
                }
80
 
                port = atoi(argv[optind]);
81
 
                if (port <= 0) {
82
 
                        fprintf(stderr, "bad port (%s)\n", argv[optind]);
83
 
                        usage();
84
 
                }
85
 
        }
86
 
 
87
 
        main_thread(port);
88
 
 
89
 
        fprintf(stderr, "Bye.\n");
90
 
 
91
 
        exit(0);
 
58
    int port = PORT;
 
59
    int c;
 
60
 
 
61
    if (argc > 0 && argv[0] != NULL && argv[0][0] != '\0')
 
62
        progname = argv[0];
 
63
 
 
64
    while ((c = getopt(argc, argv, "v")) != EOF) {
 
65
        switch (c) {
 
66
        case 'v':
 
67
            Py_VerboseFlag++;
 
68
            break;
 
69
        default:
 
70
            usage();
 
71
        }
 
72
    }
 
73
 
 
74
    if (optind < argc) {
 
75
        if (optind+1 < argc) {
 
76
            oprogname();
 
77
            fprintf(stderr, "too many arguments\n");
 
78
            usage();
 
79
        }
 
80
        port = atoi(argv[optind]);
 
81
        if (port <= 0) {
 
82
            fprintf(stderr, "bad port (%s)\n", argv[optind]);
 
83
            usage();
 
84
        }
 
85
    }
 
86
 
 
87
    main_thread(port);
 
88
 
 
89
    fprintf(stderr, "Bye.\n");
 
90
 
 
91
    exit(0);
92
92
}
93
93
 
94
94
static char usage_line[] = "usage: %s [port]\n";
96
96
static void
97
97
usage(void)
98
98
{
99
 
        fprintf(stderr, usage_line, progname);
100
 
        exit(2);
 
99
    fprintf(stderr, usage_line, progname);
 
100
    exit(2);
101
101
}
102
102
 
103
103
static void
104
104
main_thread(int port)
105
105
{
106
 
        int sock, conn, size, i;
107
 
        struct sockaddr_in addr, clientaddr;
 
106
    int sock, conn, size, i;
 
107
    struct sockaddr_in addr, clientaddr;
108
108
 
109
 
        sock = socket(PF_INET, SOCK_STREAM, 0);
110
 
        if (sock < 0) {
111
 
                oprogname();
112
 
                perror("can't create socket");
113
 
                exit(1);
114
 
        }
 
109
    sock = socket(PF_INET, SOCK_STREAM, 0);
 
110
    if (sock < 0) {
 
111
        oprogname();
 
112
        perror("can't create socket");
 
113
        exit(1);
 
114
    }
115
115
 
116
116
#ifdef SO_REUSEADDR
117
 
        i = 1;
118
 
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof i);
 
117
    i = 1;
 
118
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof i);
119
119
#endif
120
120
 
121
 
        memset((char *)&addr, '\0', sizeof addr);
122
 
        addr.sin_family = AF_INET;
123
 
        addr.sin_port = htons(port);
124
 
        addr.sin_addr.s_addr = 0L;
125
 
        if (bind(sock, (struct sockaddr *)&addr, sizeof addr) < 0) {
126
 
                oprogname();
127
 
                perror("can't bind socket to address");
128
 
                exit(1);
129
 
        }
130
 
 
131
 
        if (listen(sock, 5) < 0) {
132
 
                oprogname();
133
 
                perror("can't listen on socket");
134
 
                exit(1);
135
 
        }
136
 
 
137
 
        fprintf(stderr, "Listening on port %d...\n", port);
138
 
 
139
 
        for (i = 0; ; i++) {
140
 
                size = sizeof clientaddr;
141
 
                memset((char *) &clientaddr, '\0', size);
142
 
                conn = accept(sock, (struct sockaddr *) &clientaddr, &size);
143
 
                if (conn < 0) {
144
 
                        oprogname();
145
 
                        perror("can't accept connection from socket");
146
 
                        exit(1);
147
 
                }
148
 
 
149
 
                size = sizeof addr;
150
 
                memset((char *) &addr, '\0', size);
151
 
                if (getsockname(conn, (struct sockaddr *)&addr, &size) < 0) {
152
 
                        oprogname();
153
 
                        perror("can't get socket name of connection");
154
 
                        exit(1);
155
 
                }
156
 
                if (clientaddr.sin_addr.s_addr != addr.sin_addr.s_addr) {
157
 
                        oprogname();
158
 
                        perror("connection from non-local host refused");
159
 
                        fprintf(stderr, "(addr=%lx, clientaddr=%lx)\n",
160
 
                                ntohl(addr.sin_addr.s_addr),
161
 
                                ntohl(clientaddr.sin_addr.s_addr));
162
 
                        close(conn);
163
 
                        continue;
164
 
                }
165
 
                if (i == 4) {
166
 
                        close(conn);
167
 
                        break;
168
 
                }
169
 
                create_thread(conn, &clientaddr);
170
 
        }
171
 
 
172
 
        close(sock);
173
 
 
174
 
        if (gtstate) {
175
 
                PyEval_AcquireThread(gtstate);
176
 
                gtstate = NULL;
177
 
                Py_Finalize();
178
 
                /* And a second time, just because we can. */
179
 
                Py_Finalize(); /* This should be harmless. */
180
 
        }
181
 
        exit(0);
 
121
    memset((char *)&addr, '\0', sizeof addr);
 
122
    addr.sin_family = AF_INET;
 
123
    addr.sin_port = htons(port);
 
124
    addr.sin_addr.s_addr = 0L;
 
125
    if (bind(sock, (struct sockaddr *)&addr, sizeof addr) < 0) {
 
126
        oprogname();
 
127
        perror("can't bind socket to address");
 
128
        exit(1);
 
129
    }
 
130
 
 
131
    if (listen(sock, 5) < 0) {
 
132
        oprogname();
 
133
        perror("can't listen on socket");
 
134
        exit(1);
 
135
    }
 
136
 
 
137
    fprintf(stderr, "Listening on port %d...\n", port);
 
138
 
 
139
    for (i = 0; ; i++) {
 
140
        size = sizeof clientaddr;
 
141
        memset((char *) &clientaddr, '\0', size);
 
142
        conn = accept(sock, (struct sockaddr *) &clientaddr, &size);
 
143
        if (conn < 0) {
 
144
            oprogname();
 
145
            perror("can't accept connection from socket");
 
146
            exit(1);
 
147
        }
 
148
 
 
149
        size = sizeof addr;
 
150
        memset((char *) &addr, '\0', size);
 
151
        if (getsockname(conn, (struct sockaddr *)&addr, &size) < 0) {
 
152
            oprogname();
 
153
            perror("can't get socket name of connection");
 
154
            exit(1);
 
155
        }
 
156
        if (clientaddr.sin_addr.s_addr != addr.sin_addr.s_addr) {
 
157
            oprogname();
 
158
            perror("connection from non-local host refused");
 
159
            fprintf(stderr, "(addr=%lx, clientaddr=%lx)\n",
 
160
                ntohl(addr.sin_addr.s_addr),
 
161
                ntohl(clientaddr.sin_addr.s_addr));
 
162
            close(conn);
 
163
            continue;
 
164
        }
 
165
        if (i == 4) {
 
166
            close(conn);
 
167
            break;
 
168
        }
 
169
        create_thread(conn, &clientaddr);
 
170
    }
 
171
 
 
172
    close(sock);
 
173
 
 
174
    if (gtstate) {
 
175
        PyEval_AcquireThread(gtstate);
 
176
        gtstate = NULL;
 
177
        Py_Finalize();
 
178
        /* And a second time, just because we can. */
 
179
        Py_Finalize(); /* This should be harmless. */
 
180
    }
 
181
    exit(0);
182
182
}
183
183
 
184
184
static void
185
185
create_thread(int conn, struct sockaddr_in *addr)
186
186
{
187
 
        struct workorder *work;
188
 
        pthread_t tdata;
189
 
 
190
 
        work = malloc(sizeof(struct workorder));
191
 
        if (work == NULL) {
192
 
                oprogname();
193
 
                fprintf(stderr, "out of memory for thread.\n");
194
 
                close(conn);
195
 
                return;
196
 
        }
197
 
        work->conn = conn;
198
 
        work->addr = *addr;
199
 
 
200
 
        init_python();
201
 
 
202
 
        if (pthread_create(&tdata, NULL, (void *)service_thread, work) < 0) {
203
 
                oprogname();
204
 
                perror("can't create new thread");
205
 
                close(conn);
206
 
                return;
207
 
        }
208
 
 
209
 
        if (pthread_detach(tdata) < 0) {
210
 
                oprogname();
211
 
                perror("can't detach from thread");
212
 
        }
 
187
    struct workorder *work;
 
188
    pthread_t tdata;
 
189
 
 
190
    work = malloc(sizeof(struct workorder));
 
191
    if (work == NULL) {
 
192
        oprogname();
 
193
        fprintf(stderr, "out of memory for thread.\n");
 
194
        close(conn);
 
195
        return;
 
196
    }
 
197
    work->conn = conn;
 
198
    work->addr = *addr;
 
199
 
 
200
    init_python();
 
201
 
 
202
    if (pthread_create(&tdata, NULL, (void *)service_thread, work) < 0) {
 
203
        oprogname();
 
204
        perror("can't create new thread");
 
205
        close(conn);
 
206
        return;
 
207
    }
 
208
 
 
209
    if (pthread_detach(tdata) < 0) {
 
210
        oprogname();
 
211
        perror("can't detach from thread");
 
212
    }
213
213
}
214
214
 
215
215
static PyThreadState *the_tstate;
219
219
static void
220
220
init_python(void)
221
221
{
222
 
        if (gtstate)
223
 
                return;
224
 
        Py_Initialize(); /* Initialize the interpreter */
225
 
        PyEval_InitThreads(); /* Create (and acquire) the interpreter lock */
226
 
        gtstate = PyEval_SaveThread(); /* Release the thread state */
 
222
    if (gtstate)
 
223
        return;
 
224
    Py_Initialize(); /* Initialize the interpreter */
 
225
    PyEval_InitThreads(); /* Create (and acquire) the interpreter lock */
 
226
    gtstate = PyEval_SaveThread(); /* Release the thread state */
227
227
}
228
228
 
229
229
static void *
230
230
service_thread(struct workorder *work)
231
231
{
232
 
        FILE *input, *output;
233
 
 
234
 
        fprintf(stderr, "Start thread for connection %d.\n", work->conn);
235
 
 
236
 
        ps();
237
 
 
238
 
        input = fdopen(work->conn, "r");
239
 
        if (input == NULL) {
240
 
                oprogname();
241
 
                perror("can't create input stream");
242
 
                goto done;
243
 
        }
244
 
 
245
 
        output = fdopen(work->conn, "w");
246
 
        if (output == NULL) {
247
 
                oprogname();
248
 
                perror("can't create output stream");
249
 
                fclose(input);
250
 
                goto done;
251
 
        }
252
 
 
253
 
        setvbuf(input, NULL, _IONBF, 0);
254
 
        setvbuf(output, NULL, _IONBF, 0);
255
 
 
256
 
        run_interpreter(input, output);
257
 
 
258
 
        fclose(input);
259
 
        fclose(output);
 
232
    FILE *input, *output;
 
233
 
 
234
    fprintf(stderr, "Start thread for connection %d.\n", work->conn);
 
235
 
 
236
    ps();
 
237
 
 
238
    input = fdopen(work->conn, "r");
 
239
    if (input == NULL) {
 
240
        oprogname();
 
241
        perror("can't create input stream");
 
242
        goto done;
 
243
    }
 
244
 
 
245
    output = fdopen(work->conn, "w");
 
246
    if (output == NULL) {
 
247
        oprogname();
 
248
        perror("can't create output stream");
 
249
        fclose(input);
 
250
        goto done;
 
251
    }
 
252
 
 
253
    setvbuf(input, NULL, _IONBF, 0);
 
254
    setvbuf(output, NULL, _IONBF, 0);
 
255
 
 
256
    run_interpreter(input, output);
 
257
 
 
258
    fclose(input);
 
259
    fclose(output);
260
260
 
261
261
  done:
262
 
        fprintf(stderr, "End thread for connection %d.\n", work->conn);
263
 
        close(work->conn);
264
 
        free(work);
 
262
    fprintf(stderr, "End thread for connection %d.\n", work->conn);
 
263
    close(work->conn);
 
264
    free(work);
265
265
}
266
266
 
267
267
static void
268
268
oprogname(void)
269
269
{
270
 
        int save = errno;
271
 
        fprintf(stderr, "%s: ", progname);
272
 
        errno = save;
 
270
    int save = errno;
 
271
    fprintf(stderr, "%s: ", progname);
 
272
    errno = save;
273
273
}
274
274
 
275
275
static void
276
276
run_interpreter(FILE *input, FILE *output)
277
277
{
278
 
        PyThreadState *tstate;
279
 
        PyObject *new_stdin, *new_stdout;
280
 
        PyObject *mainmod, *globals;
281
 
        char buffer[1000];
282
 
        char *p, *q;
283
 
        int n, end;
284
 
 
285
 
        PyEval_AcquireLock();
286
 
        tstate = Py_NewInterpreter();
287
 
        if (tstate == NULL) {
288
 
                fprintf(output, "Sorry -- can't create an interpreter\n");
289
 
                return;
290
 
        }
291
 
 
292
 
        mainmod = PyImport_AddModule("__main__");
293
 
        globals = PyModule_GetDict(mainmod);
294
 
        Py_INCREF(globals);
295
 
 
296
 
        new_stdin = PyFile_FromFile(input, "<socket-in>", "r", NULL);
297
 
        new_stdout = PyFile_FromFile(output, "<socket-out>", "w", NULL);
298
 
 
299
 
        PySys_SetObject("stdin", new_stdin);
300
 
        PySys_SetObject("stdout", new_stdout);
301
 
        PySys_SetObject("stderr", new_stdout);
302
 
 
303
 
        for (n = 1; !PyErr_Occurred(); n++) {
304
 
                Py_BEGIN_ALLOW_THREADS
305
 
                fprintf(output, "%d> ", n);
306
 
                p = fgets(buffer, sizeof buffer, input);
307
 
                Py_END_ALLOW_THREADS
308
 
 
309
 
                if (p == NULL)
310
 
                        break;
311
 
                if (p[0] == '\377' && p[1] == '\354')
312
 
                        break;
313
 
 
314
 
                q = strrchr(p, '\r');
315
 
                if (q && q[1] == '\n' && q[2] == '\0') {
316
 
                        *q++ = '\n';
317
 
                        *q++ = '\0';
318
 
                }
319
 
 
320
 
                while (*p && isspace(*p))
321
 
                        p++;
322
 
                if (p[0] == '#' || p[0] == '\0')
323
 
                        continue;
324
 
 
325
 
                end = run_command(buffer, globals);
326
 
                if (end < 0)
327
 
                        PyErr_Print();
328
 
 
329
 
                if (end)
330
 
                        break;
331
 
        }
332
 
 
333
 
        Py_XDECREF(globals);
334
 
        Py_XDECREF(new_stdin);
335
 
        Py_XDECREF(new_stdout);
336
 
 
337
 
        Py_EndInterpreter(tstate);
338
 
        PyEval_ReleaseLock();
339
 
 
340
 
        fprintf(output, "Goodbye!\n");
 
278
    PyThreadState *tstate;
 
279
    PyObject *new_stdin, *new_stdout;
 
280
    PyObject *mainmod, *globals;
 
281
    char buffer[1000];
 
282
    char *p, *q;
 
283
    int n, end;
 
284
 
 
285
    PyEval_AcquireLock();
 
286
    tstate = Py_NewInterpreter();
 
287
    if (tstate == NULL) {
 
288
        fprintf(output, "Sorry -- can't create an interpreter\n");
 
289
        return;
 
290
    }
 
291
 
 
292
    mainmod = PyImport_AddModule("__main__");
 
293
    globals = PyModule_GetDict(mainmod);
 
294
    Py_INCREF(globals);
 
295
 
 
296
    new_stdin = PyFile_FromFile(input, "<socket-in>", "r", NULL);
 
297
    new_stdout = PyFile_FromFile(output, "<socket-out>", "w", NULL);
 
298
 
 
299
    PySys_SetObject("stdin", new_stdin);
 
300
    PySys_SetObject("stdout", new_stdout);
 
301
    PySys_SetObject("stderr", new_stdout);
 
302
 
 
303
    for (n = 1; !PyErr_Occurred(); n++) {
 
304
        Py_BEGIN_ALLOW_THREADS
 
305
        fprintf(output, "%d> ", n);
 
306
        p = fgets(buffer, sizeof buffer, input);
 
307
        Py_END_ALLOW_THREADS
 
308
 
 
309
        if (p == NULL)
 
310
            break;
 
311
        if (p[0] == '\377' && p[1] == '\354')
 
312
            break;
 
313
 
 
314
        q = strrchr(p, '\r');
 
315
        if (q && q[1] == '\n' && q[2] == '\0') {
 
316
            *q++ = '\n';
 
317
            *q++ = '\0';
 
318
        }
 
319
 
 
320
        while (*p && isspace(*p))
 
321
            p++;
 
322
        if (p[0] == '#' || p[0] == '\0')
 
323
            continue;
 
324
 
 
325
        end = run_command(buffer, globals);
 
326
        if (end < 0)
 
327
            PyErr_Print();
 
328
 
 
329
        if (end)
 
330
            break;
 
331
    }
 
332
 
 
333
    Py_XDECREF(globals);
 
334
    Py_XDECREF(new_stdin);
 
335
    Py_XDECREF(new_stdout);
 
336
 
 
337
    Py_EndInterpreter(tstate);
 
338
    PyEval_ReleaseLock();
 
339
 
 
340
    fprintf(output, "Goodbye!\n");
341
341
}
342
342
 
343
343
static int
344
344
run_command(char *buffer, PyObject *globals)
345
345
{
346
 
        PyObject *m, *d, *v;
347
 
        fprintf(stderr, "run_command: %s", buffer);
348
 
        if (strchr(buffer, '\n') == NULL)
349
 
                fprintf(stderr, "\n");
350
 
        v = PyRun_String(buffer, Py_single_input, globals, globals);
351
 
        if (v == NULL) {
352
 
                if (PyErr_Occurred() == PyExc_SystemExit) {
353
 
                        PyErr_Clear();
354
 
                        return 1;
355
 
                }
356
 
                PyErr_Print();
357
 
                return 0;
358
 
        }
359
 
        Py_DECREF(v);
360
 
        return 0;
 
346
    PyObject *m, *d, *v;
 
347
    fprintf(stderr, "run_command: %s", buffer);
 
348
    if (strchr(buffer, '\n') == NULL)
 
349
        fprintf(stderr, "\n");
 
350
    v = PyRun_String(buffer, Py_single_input, globals, globals);
 
351
    if (v == NULL) {
 
352
        if (PyErr_Occurred() == PyExc_SystemExit) {
 
353
            PyErr_Clear();
 
354
            return 1;
 
355
        }
 
356
        PyErr_Print();
 
357
        return 0;
 
358
    }
 
359
    Py_DECREF(v);
 
360
    return 0;
361
361
}
362
362
 
363
363
static void
364
364
ps(void)
365
365
{
366
 
        char buffer[100];
367
 
        PyOS_snprintf(buffer, sizeof(buffer),
368
 
                      "ps -l -p %d </dev/null | sed 1d\n", getpid());
369
 
        system(buffer);
 
366
    char buffer[100];
 
367
    PyOS_snprintf(buffer, sizeof(buffer),
 
368
                  "ps -l -p %d </dev/null | sed 1d\n", getpid());
 
369
    system(buffer);
370
370
}