r25598: Add missing become_root/unbecome_root around calls of add_aliases.
[sfrench/samba-autobuild/.git] / source3 / 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 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "py_conv.h"
21
22 /* Helper for rpcstr_pull() function */
23
24 static void fstr_pull(fstring str, UNISTR *uni)
25 {
26         rpcstr_pull(str, uni->buffer, sizeof(fstring), -1, STR_TERMINATE);
27 }
28
29 static void fstr_pull2(fstring str, UNISTR2 *uni)
30 {
31         rpcstr_pull(str, uni->buffer, sizeof(fstring), -1, STR_TERMINATE);
32 }
33
34 /* Convert a structure to a Python dict */
35
36 PyObject *from_struct(void *s, struct pyconv *conv)
37 {
38         PyObject *obj, *item;
39         int i;
40
41         obj = PyDict_New();
42
43         for (i = 0; conv[i].name; i++) {
44                 switch (conv[i].type) {
45                 case PY_UNISTR: {
46                         UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
47                         fstring str = "";
48
49                         if (u->buffer)
50                                 fstr_pull(str, u);
51
52                         item = PyString_FromString(str);
53                         PyDict_SetItemString(obj, conv[i].name, item);
54
55                         break;
56                 }
57                 case PY_UNISTR2: {
58                         UNISTR2 *u = (UNISTR2 *)((char *)s + conv[i].offset);
59                         fstring str = "";
60
61                         if (u->buffer)
62                                 fstr_pull2(str, u);
63
64                         item = PyString_FromString(str);
65                         PyDict_SetItemString(obj, conv[i].name, item);
66
67                         break;
68                 }
69                 case PY_UINT32: {
70                         uint32 *u = (uint32 *)((char *)s + conv[i].offset);
71
72                         item = PyInt_FromLong(*u);
73                         PyDict_SetItemString(obj, conv[i].name, item);
74                         
75                         break;
76                 }
77                 case PY_UINT16: {
78                         uint16 *u = (uint16 *)((char *)s + conv[i].offset);
79
80                         item = PyInt_FromLong(*u);
81                         PyDict_SetItemString(obj, conv[i].name, item);
82
83                         break;
84                 }
85                 case PY_STRING: {
86                         char *str = (char *)s + conv[i].offset;
87
88                         item = PyString_FromString(str);
89                         PyDict_SetItemString(obj, conv[i].name, item);
90
91                         break;
92                 }
93                 case PY_UID: {
94                         uid_t *uid = (uid_t *)((char *)s + conv[i].offset);
95
96                         item = PyInt_FromLong(*uid);
97                         PyDict_SetItemString(obj, conv[i].name, item);
98
99                         break;
100                 }
101                 case PY_GID: {
102                         gid_t *gid = (gid_t *)((char *)s + conv[i].offset);
103
104                         item = PyInt_FromLong(*gid);
105                         PyDict_SetItemString(obj, conv[i].name, item);
106
107                         break;
108                 }
109                 default:
110                         
111                         break;
112                 }
113         }
114
115         return obj;
116 }
117
118 /* Convert a Python dict to a structure */
119
120 BOOL to_struct(void *s, PyObject *dict, struct pyconv *conv)
121 {
122         PyObject *visited, *key, *value;
123         BOOL result = False;
124         int i;
125
126         visited = PyDict_New();
127
128         for (i = 0; conv[i].name; i++) {
129                 PyObject *obj;
130                 
131                 obj = PyDict_GetItemString(dict, conv[i].name);
132
133                 if (!obj)
134                         goto done;
135                 
136                 switch (conv[i].type) {
137                 case PY_UNISTR: {
138                         UNISTR *u = (UNISTR *)((char *)s + conv[i].offset);
139                         char *str = "";
140
141                         if (!PyString_Check(obj))
142                                 goto done;
143
144                         str = PyString_AsString(obj);
145                         init_unistr(u, str);
146                         
147                         break;
148                 }
149                 case PY_UINT32: {
150                         uint32 *u = (uint32 *)((char *)s + conv[i].offset);
151
152                         if (!PyInt_Check(obj))
153                                 goto done;
154
155                         *u = PyInt_AsLong(obj);
156
157                         break;
158                 }
159                 case PY_UINT16: {
160                         uint16 *u = (uint16 *)((char *)s + conv[i].offset);
161
162                         if (!PyInt_Check(obj)) 
163                                 goto done;
164
165                         *u = PyInt_AsLong(obj);
166                         break;
167                 }
168                 default:
169                         break;
170                 }
171
172                 /* Mark as visited */
173
174                 PyDict_SetItemString(visited, conv[i].name, 
175                                      PyInt_FromLong(1));
176         }
177
178         /* Iterate over each item in the input dictionary and see if it was
179            visited.  If it wasn't then the user has added some extra crap
180            to the dictionary. */
181
182         i = 0;
183
184         while (PyDict_Next(dict, &i, &key, &value)) {
185                 if (!PyDict_GetItem(visited, key))
186                         goto done;
187         }
188
189         result = True;
190
191 done:
192         /* We must decrement the reference count here or the visited
193            dictionary will not be freed. */
194                
195         Py_DECREF(visited);
196
197         return result;
198 }
199
200 /* Convert a NULL terminated list of NULL terminated unicode strings
201    to a list of (char *) strings */
202
203 PyObject *from_unistr_list(uint16 *dependentfiles)
204 {
205         PyObject *list;
206         int offset = 0;
207
208         list = PyList_New(0);
209
210         while (*(dependentfiles + offset) != 0) {
211                 fstring name;
212                 int len;
213
214                 len = rpcstr_pull(name, dependentfiles + offset,
215                                   sizeof(fstring), -1, STR_TERMINATE);
216
217                 offset += len / 2;
218                 PyList_Append(list, PyString_FromString(name));
219         }
220
221         return list;
222 }