Initial import
[samba] / source / python / py_conv.c
1 /* 
2    Python wrappers for DCERPC/SMB client routines.
3
4    Copyright (C) Tim Potter, 2002
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "py_conv.h"
22
23 /* Helper for rpcstr_pull() function */
24
25 static void fstr_pull(fstring str, UNISTR *uni)
26 {
27         rpcstr_pull(str, uni->buffer, sizeof(fstring), -1, STR_TERMINATE);
28 }
29
30 static void fstr_pull2(fstring str, UNISTR2 *uni)
31 {
32         rpcstr_pull(str, uni->buffer, sizeof(fstring), -1, STR_TERMINATE);
33 }
34
35 /* Convert a structure to a Python dict */
36
37 PyObject *from_struct(void *s, struct pyconv *conv)
38 {
39         PyObject *obj, *item;
40         int i;
41
42         obj = PyDict_New();
43
44         for (i = 0; conv[i].name; i++) {
45                 switch (conv[i].type) {
46                 case PY_UNISTR: {
47                         UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
48                         fstring str = "";
49
50                         if (u->buffer)
51                                 fstr_pull(str, u);
52
53                         item = PyString_FromString(str);
54                         PyDict_SetItemString(obj, conv[i].name, item);
55
56                         break;
57                 }
58                 case PY_UNISTR2: {
59                         UNISTR2 *u = (UNISTR2 *)((char *)s + conv[i].offset);
60                         fstring str = "";
61
62                         if (u->buffer)
63                                 fstr_pull2(str, u);
64
65                         item = PyString_FromString(str);
66                         PyDict_SetItemString(obj, conv[i].name, item);
67
68                         break;
69                 }
70                 case PY_UINT32: {
71                         uint32 *u = (uint32 *)((char *)s + conv[i].offset);
72
73                         item = PyInt_FromLong(*u);
74                         PyDict_SetItemString(obj, conv[i].name, item);
75                         
76                         break;
77                 }
78                 case PY_UINT16: {
79                         uint16 *u = (uint16 *)((char *)s + conv[i].offset);
80
81                         item = PyInt_FromLong(*u);
82                         PyDict_SetItemString(obj, conv[i].name, item);
83
84                         break;
85                 }
86                 case PY_STRING: {
87                         char *str = (char *)s + conv[i].offset;
88
89                         item = PyString_FromString(str);
90                         PyDict_SetItemString(obj, conv[i].name, item);
91
92                         break;
93                 }
94                 case PY_UID: {
95                         uid_t *uid = (uid_t *)((char *)s + conv[i].offset);
96
97                         item = PyInt_FromLong(*uid);
98                         PyDict_SetItemString(obj, conv[i].name, item);
99
100                         break;
101                 }
102                 case PY_GID: {
103                         gid_t *gid = (gid_t *)((char *)s + conv[i].offset);
104
105                         item = PyInt_FromLong(*gid);
106                         PyDict_SetItemString(obj, conv[i].name, item);
107
108                         break;
109                 }
110                 default:
111                         
112                         break;
113                 }
114         }
115
116         return obj;
117 }
118
119 /* Convert a Python dict to a structure */
120
121 BOOL to_struct(void *s, PyObject *dict, struct pyconv *conv)
122 {
123         PyObject *visited, *key, *value;
124         BOOL result = False;
125         int i;
126
127         visited = PyDict_New();
128
129         for (i = 0; conv[i].name; i++) {
130                 PyObject *obj;
131                 
132                 obj = PyDict_GetItemString(dict, conv[i].name);
133
134                 if (!obj)
135                         goto done;
136                 
137                 switch (conv[i].type) {
138                 case PY_UNISTR: {
139                         UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
140                         char *str = "";
141
142                         if (!PyString_Check(obj))
143                                 goto done;
144
145                         str = PyString_AsString(obj);
146                         init_unistr(u, str);
147                         
148                         break;
149                 }
150                 case PY_UINT32: {
151                         uint32 *u = (uint32 *)((char *)s + conv[i].offset);
152
153                         if (!PyInt_Check(obj))
154                                 goto done;
155
156                         *u = PyInt_AsLong(obj);
157
158                         break;
159                 }
160                 case PY_UINT16: {
161                         uint16 *u = (uint16 *)((char *)s + conv[i].offset);
162
163                         if (!PyInt_Check(obj)) 
164                                 goto done;
165
166                         *u = PyInt_AsLong(obj);
167                         break;
168                 }
169                 default:
170                         break;
171                 }
172
173                 /* Mark as visited */
174
175                 PyDict_SetItemString(visited, conv[i].name, 
176                                      PyInt_FromLong(1));
177         }
178
179         /* Iterate over each item in the input dictionary and see if it was
180            visited.  If it wasn't then the user has added some extra crap
181            to the dictionary. */
182
183         i = 0;
184
185         while (PyDict_Next(dict, &i, &key, &value)) {
186                 if (!PyDict_GetItem(visited, key))
187                         goto done;
188         }
189
190         result = True;
191
192 done:
193         /* We must decrement the reference count here or the visited
194            dictionary will not be freed. */
195                
196         Py_DECREF(visited);
197
198         return result;
199 }
200
201 /* Convert a NULL terminated list of NULL terminated unicode strings
202    to a list of (char *) strings */
203
204 PyObject *from_unistr_list(uint16 *dependentfiles)
205 {
206         PyObject *list;
207         int offset = 0;
208
209         list = PyList_New(0);
210
211         while (*(dependentfiles + offset) != 0) {
212                 fstring name;
213                 int len;
214
215                 len = rpcstr_pull(name, dependentfiles + offset,
216                                   sizeof(fstring), -1, STR_TERMINATE);
217
218                 offset += len / 2;
219                 PyList_Append(list, PyString_FromString(name));
220         }
221
222         return list;
223 }