source: TI05-delivery/trunk/src/python_ext/bbftpc.c @ 1157

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/python_ext/bbftpc.c@1157
Revision 1157, 3.5 KB checked in by spascoe, 14 years ago (diff)

Client-side python embedding is being implemented but doesn't pass the
test cases yet.

I've uncovered a bug (see #343) which needs fixing before the embedded client
can be fully debugged.

Line 
1/**
2 * NDG python embedded bbftp daemon module.
3 *
4 * @author Stephen Pascoe
5 *
6 * Copyright (C) 2006 CCLRC & NERC
7 *
8 * This software may be distributed under the terms of the Q Public Licence, version 1.0 or later.
9 *
10 */
11
12#include <Python.h>
13#include <stdio.h>
14
15extern char **environ;
16#define TRUE 1
17#define FALSE 0
18
19int bbftpc_main(int argc, char **argv, char **envp);
20
21/**
22 * Routines for constructing a argc/argv style argument list from a python sequence.
23 */
24
25struct ndg_argv {
26  int argc;         /// Total number of arguments.
27  char **argv;     /// Argument array.
28  int next;         /// index of next empty (and unallocated) argument.
29};
30
31/**
32 * Initialise a structure.
33 * @return TRUE on success or FALSE on a memory error.
34 */
35int ndg_argv_init(struct ndg_argv *argv_s, int argc) {
36  argv_s->argc = argc;
37
38  if ((argv_s->argv = (char **)malloc(sizeof(struct ndg_argv))) == NULL) {
39    return FALSE;
40  }
41
42  argv_s->next = 0;
43
44  return TRUE;
45}
46
47/**
48 * Free a structure.  \a argv_s should be cleared first with \c ndg_argv_clear().
49 *
50 * @return TRUE on success or FALSE if the structure isn't empty.
51 */
52int ndg_argv_free(struct ndg_argv *argv_s) {
53  if (argv_s->next != 0) return FALSE;
54  free(argv_s->argv);
55  return TRUE;
56}
57
58/**
59 * Clear all arguments from the structure.
60 *
61 */
62void ndg_argv_clear(struct ndg_argv *argv_s) {
63  char *arg;
64  while (argv_s->next > 0) {
65    argv_s->next--;
66    arg = argv_s->argv[argv_s->next];
67    free(arg);
68  }
69}
70
71/**
72 * Add an argument.
73 *
74 * @return TRUE on success or FALSE on an error.
75 */
76int ndg_argv_add(struct ndg_argv *argv_s, char *arg) {
77  char **arg_p;
78
79  if (argv_s->argc == argv_s->next) return FALSE;
80  arg_p = &(argv_s->argv[argv_s->next]);
81  if ((*arg_p = (char *)malloc(strlen(arg))) == NULL) {
82    return FALSE;
83  }
84  strcpy(*arg_p, arg);
85  argv_s->next++;
86  return TRUE;
87}
88
89
90
91/**
92 * Main entry point into the bbftp client from python.
93 */
94static PyObject *bbftpc_run(PyObject *self, PyObject *args) {
95  int i, argc;
96  struct ndg_argv argv_s;
97  char *arg;
98  PyObject *client_args, *item;
99
100  if (!PyArg_ParseTuple(args, "O", &client_args)) {
101    return NULL;
102  }
103  Py_INCREF(client_args);
104
105  /*
106   * Convert arguments into a standard argv sequence.
107   */
108  argc = PySequence_Size(client_args);
109  if (!ndg_argv_init(&argv_s, argc + 1)) {
110    PyErr_SetString(PyExc_MemoryError, "malloc failed");
111    Py_DECREF(client_args);
112    return NULL;
113  }
114
115  ndg_argv_add(&argv_s, "bbftpc_run");
116  for (i=0; i<argc; i++) {
117    if ((item = PySequence_GetItem(client_args, i)) == NULL) {
118      ndg_argv_clear(&argv_s); ndg_argv_free(&argv_s);
119      Py_DECREF(client_args);
120      return NULL;
121    }
122    if ((arg = PyString_AsString(item)) == NULL) {
123      ndg_argv_clear(&argv_s); ndg_argv_free(&argv_s);
124      Py_DECREF(item);
125      Py_DECREF(client_args);
126      return NULL;
127    }
128
129    if (!ndg_argv_add(&argv_s, arg)) {
130      PyErr_SetString(PyExc_MemoryError, "ndg_argv_add failed");
131      ndg_argv_clear(&argv_s); ndg_argv_free(&argv_s);
132      Py_DECREF(client_args);
133      Py_DECREF(item);
134    }
135
136    Py_DECREF(item);
137
138  }
139  Py_DECREF(client_args);
140
141  for (i=0; i<argv_s.argc; i++) {
142    fprintf(stderr, "delivery.bbftpc.run argument: %s\n", argv_s.argv[i]);
143  }
144 
145
146  bbftpc_main(argv_s.argc, argv_s.argv, environ);
147  ndg_argv_clear(&argv_s); ndg_argv_free(&argv_s);
148
149  Py_RETURN_NONE;
150}
151
152static PyMethodDef BbftpcMethods[] = {
153  {
154    "run", bbftpc_run, METH_VARARGS,
155    "Execute the bbftp client.\n"
156    "\n"
157    "@param args: command line arguments"
158  },
159  {NULL, NULL, 0, NULL}
160};
161
162PyMODINIT_FUNC initbbftpc(void) {
163  (void) Py_InitModule("bbftpc", BbftpcMethods);
164}
Note: See TracBrowser for help on using the repository browser.