- Got rid of newmodule.c
[python/dscho.git] / RISCOS / Modules / riscosmodule.c
blobadcc1286bcac7c583b9caeae662569b2644b5de5
1 /* RISCOS module implementation */
3 #include "oslib/osfscontrol.h"
4 #include "oslib/osgbpb.h"
5 #include "oslib/os.h"
6 #include "oslib/osfile.h"
7 #include "unixstuff.h"
9 #include "Python.h"
10 #include "structseq.h"
12 #include <errno.h>
14 static os_error *e;
16 /*static PyObject *RiscosError;*/ /* Exception riscos.error */
18 static PyObject *riscos_error(char *s)
20 PyErr_SetString(PyExc_OSError, s);
21 return NULL;
24 static PyObject *riscos_oserror(void)
26 return riscos_error(e->errmess);
30 /* RISCOS file commands */
32 static PyObject *riscos_remove(PyObject *self,PyObject *args)
33 { char *path1;
34 if (!PyArg_Parse(args, "s", &path1)) return NULL;
35 if (remove(path1)) return PyErr_SetFromErrno(PyExc_OSError);
36 Py_INCREF(Py_None);
37 return Py_None;
40 static PyObject *riscos_rename(PyObject *self,PyObject *args)
41 { char *path1, *path2;
42 if (!PyArg_Parse(args, "(ss)", &path1, &path2)) return NULL;
43 if (rename(path1,path2)) return PyErr_SetFromErrno(PyExc_OSError);
44 Py_INCREF(Py_None);
45 return Py_None;
48 static PyObject *riscos_system(PyObject *self,PyObject *args)
49 { char *command;
50 if (!PyArg_Parse(args, "s", &command)) return NULL;
51 return PyInt_FromLong(system(command));
54 static PyObject *riscos_chdir(PyObject *self,PyObject *args)
55 { char *path;
56 if (!PyArg_Parse(args, "s", &path)) return NULL;
57 e=xosfscontrol_dir(path);
58 if(e) return riscos_oserror();
59 Py_INCREF(Py_None);
60 return Py_None;
63 static PyObject *canon(char *path)
64 { int len;
65 PyObject *obj;
66 char *buf;
67 e=xosfscontrol_canonicalise_path(path,0,0,0,0,&len);
68 if(e) return riscos_oserror();
69 obj=PyString_FromStringAndSize(NULL,-len);
70 if(obj==NULL) return NULL;
71 buf=PyString_AsString(obj);
72 e=xosfscontrol_canonicalise_path(path,buf,0,0,1-len,&len);
73 if(len!=1) return riscos_error("Error expanding path");
74 if(!e) return obj;
75 Py_DECREF(obj);
76 return riscos_oserror();
79 static PyObject *riscos_getcwd(PyObject *self,PyObject *args)
80 { if(!PyArg_NoArgs(args)) return NULL;
81 return canon("@");
84 static PyObject *riscos_expand(PyObject *self,PyObject *args)
85 { char *path;
86 if (!PyArg_Parse(args, "s", &path)) return NULL;
87 return canon(path);
90 static PyObject *riscos_mkdir(PyObject *self,PyObject *args)
91 { char *path;
92 int mode;
93 if (!PyArg_ParseTuple(args, "s|i", &path, &mode)) return NULL;
94 e=xosfile_create_dir(path,0);
95 if(e) return riscos_oserror();
96 Py_INCREF(Py_None);
97 return Py_None;
100 static PyObject *riscos_listdir(PyObject *self,PyObject *args)
101 { char *path,buf[256];
102 PyObject *d, *v;
103 int c=0,count;
104 if (!PyArg_Parse(args, "s", &path)) return NULL;
105 d=PyList_New(0);
106 if(!d) return NULL;
107 for(;;)
108 { e=xosgbpb_dir_entries(path,(osgbpb_string_list*)buf,
109 1,c,256,0,&count,&c);
110 if(e)
111 { Py_DECREF(d);return riscos_oserror();
113 if(count)
114 { v=PyString_FromString(buf);
115 if(!v) { Py_DECREF(d);return 0;}
116 if(PyList_Append(d,v)) {Py_DECREF(d);Py_DECREF(v);return 0;}
118 if(c==-1) break;
120 return d;
123 PyDoc_STRVAR(stat_result__doc__,
124 "stat_result: Result from stat or lstat.\n\n\
125 This object may be accessed either as a tuple of\n\
126 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
127 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
129 RiscOS: The fields st_ftype, st_attrs, and st_obtype are also available.\n\
131 See os.stat for more information.");
133 static PyStructSequence_Field stat_result_fields[] = {
134 { "st_mode", "protection bits" },
135 { "st_ino", "inode" },
136 { "st_dev", "device" },
137 { "st_nlink", "number of hard links" },
138 { "st_uid", "user ID of owner" },
139 { "st_gid", "group ID of owner" },
140 { "st_size", "total size, in bytes" },
141 { "st_atime", "time of last access" },
142 { "st_mtime", "time of last modification" },
143 { "st_ctime", "time of last change" },
144 { "st_ftype", "file type" },
145 { "st_attrs", "attributes" },
146 { "st_obtype", "object type" },
147 { 0 }
150 static PyStructSequence_Desc stat_result_desc = {
151 "riscos.stat_result",
152 stat_result__doc__,
153 stat_result_fields,
157 static PyTypeObject StatResultType;
159 static PyObject *riscos_stat(PyObject *self,PyObject *args)
161 PyObject *v;
162 char *path;
163 int ob,len;
164 bits t=0;
165 bits ld,ex,at,ft,mode;
166 if (!PyArg_Parse(args, "s", &path)) return NULL;
167 e=xosfile_read_stamped_no_path(path,&ob,&ld,&ex,&len,&at,&ft);
168 if(e) return riscos_oserror();
169 switch (ob)
170 { case osfile_IS_FILE:mode=0100000;break; /* OCTAL */
171 case osfile_IS_DIR:mode=040000;break;
172 case osfile_IS_IMAGE:mode=0140000;break;
173 default:return riscos_error("Not found");
175 if(ft!=-1) t=unixtime(ld,ex);
176 mode|=(at&7)<<6;
177 mode|=((at&112)*9)>>4;
179 v = PyStructSequence_New(&StatResultType);
181 PyStructSequence_SET_ITEM(v, 0,
182 PyInt_FromLong((long) mode)); /*st_mode*/
183 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) 0)); /*st_ino*/
184 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) 0)); /*st_dev*/
185 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) 0)); /*st_nlink*/
186 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) 0)); /*st_uid*/
187 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) 0)); /*st_gid*/
188 PyStructSequence_SET_ITEM(v, 6,
189 PyInt_FromLong((long) len)); /*st_size*/
190 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) t)); /*st_atime*/
191 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) t)); /*st_mtime*/
192 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) t)); /*st_ctime*/
193 PyStructSequence_SET_ITEM(v, 10,
194 PyInt_FromLong((long) ft)); /*file type*/
195 PyStructSequence_SET_ITEM(v, 11,
196 PyInt_FromLong((long) at)); /*attributes*/
197 PyStructSequence_SET_ITEM(v, 12,
198 PyInt_FromLong((long) ob)); /*object type*/
200 if (PyErr_Occurred()) {
201 Py_DECREF(v);
202 return NULL;
205 return v;
208 static PyObject *riscos_chmod(PyObject *self,PyObject *args)
209 { char *path;
210 bits mode;
211 bits attr;
212 attr=(mode&0x700)>>8;
213 attr|=(mode&7)<<4;
214 if (!PyArg_Parse(args, "(si)", &path,(int*)&mode)) return NULL;
215 e=xosfile_write_attr(path,attr);
216 if(e) return riscos_oserror();
217 Py_INCREF(Py_None);
218 return Py_None;
222 static PyObject *riscos_utime(PyObject *self,PyObject *args)
224 char *path;
225 long atime, mtime;
226 PyObject* arg;
228 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
229 return NULL;
231 if (arg == Py_None) {
232 /* optional time values not given */
233 Py_BEGIN_ALLOW_THREADS
234 e=xosfile_stamp(path);
235 Py_END_ALLOW_THREADS
236 if(e) return riscos_oserror();
238 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
239 PyErr_SetString(PyExc_TypeError,
240 "utime() arg 2 must be a tuple (atime, mtime)");
241 return NULL;
243 else {
244 /* catalogue info*/
245 fileswitch_object_type obj_type;
246 bits load_addr, exec_addr;
247 int size;
248 fileswitch_attr attr;
250 /* read old catalogue info */
251 Py_BEGIN_ALLOW_THREADS
252 e=xosfile_read_no_path(path, &obj_type, &load_addr, &exec_addr, &size, &attr);
253 Py_END_ALLOW_THREADS
254 if(e) return riscos_oserror();
256 /* check if load and exec address really contain filetype and date */
257 if ( (load_addr & 0xFFF00000U) != 0xFFF00000U)
258 return riscos_error("can't set date for object with load and exec addresses");
260 /* convert argument mtime to RISC OS load and exec address */
261 if(acorntime(&exec_addr, &load_addr, (time_t) mtime))
262 return riscos_oserror();
264 /* write new load and exec address */
265 Py_BEGIN_ALLOW_THREADS
266 e = xosfile_write(path, load_addr, exec_addr, attr);
267 Py_END_ALLOW_THREADS
268 if(e) return riscos_oserror();
271 Py_INCREF(Py_None);
272 return Py_None;
275 static PyObject *riscos_settype(PyObject *self,PyObject *args)
276 { char *path,*name;
277 int type;
278 if (!PyArg_Parse(args, "(si)", &path,&type))
279 { PyErr_Clear();
280 if (!PyArg_Parse(args, "(ss)", &path,&name)) return NULL;
281 e=xosfscontrol_file_type_from_string(name,(bits*)&type);
282 if(e) return riscos_oserror();
284 e=xosfile_set_type(path,type);
285 if(e) return riscos_oserror();
286 Py_INCREF(Py_None);
287 return Py_None;
290 static PyObject *riscos_getenv(PyObject *self,PyObject *args)
291 { char *name,*value;
292 if(!PyArg_Parse(args,"s",&name)) return NULL;
293 value=getenv(name);
294 if(value) return PyString_FromString(value);
295 Py_INCREF(Py_None);
296 return Py_None;
299 static PyObject *riscos_putenv(PyObject *self,PyObject *args)
300 { char *name,*value;
301 int len;
302 os_var_type type=os_VARTYPE_LITERAL_STRING;
303 if(!PyArg_ParseTuple(args,"ss|i",&name,&value,&type)) return NULL;
304 if(type!=os_VARTYPE_STRING&&type!=os_VARTYPE_MACRO&&type!=os_VARTYPE_EXPANDED
305 &&type!=os_VARTYPE_LITERAL_STRING)
306 return riscos_error("Bad putenv type");
307 len=strlen(value);
308 if(type!=os_VARTYPE_LITERAL_STRING) len++;
309 /* Other types need null terminator! */
310 e=xos_set_var_val(name,(byte*)value,len,0,type,0,0);
311 if(e) return riscos_oserror();
312 Py_INCREF(Py_None);
313 return Py_None;
316 static PyObject *riscos_delenv(PyObject *self,PyObject *args)
317 { char *name;
318 if(!PyArg_Parse(args,"s",&name)) return NULL;
319 e=xos_set_var_val(name,NULL,-1,0,0,0,0);
320 if(e) return riscos_oserror();
321 Py_INCREF(Py_None);
322 return Py_None;
325 static PyObject *riscos_getenvdict(PyObject *self,PyObject *args)
326 { PyObject *dict;
327 char value[257];
328 char *which="*";
329 int size;
330 char *context=NULL;
331 if(!PyArg_ParseTuple(args,"|s",&which)) return NULL;
332 dict = PyDict_New();
333 if (!dict) return NULL;
334 /* XXX This part ignores errors */
335 while(!xos_read_var_val(which,value,sizeof(value)-1,(int)context,
336 os_VARTYPE_EXPANDED,&size,(int *)&context,0))
337 { PyObject *v;
338 value[size]='\0';
339 v = PyString_FromString(value);
340 if (v == NULL) continue;
341 PyDict_SetItemString(dict, context, v);
342 Py_DECREF(v);
344 return dict;
347 static PyMethodDef riscos_methods[] = {
349 {"unlink", riscos_remove},
350 {"remove", riscos_remove},
351 {"rename", riscos_rename},
352 {"system", riscos_system},
353 {"rmdir", riscos_remove},
354 {"chdir", riscos_chdir},
355 {"getcwd", riscos_getcwd},
356 {"expand", riscos_expand},
357 {"mkdir", riscos_mkdir,1},
358 {"listdir", riscos_listdir},
359 {"stat", riscos_stat},
360 {"lstat", riscos_stat},
361 {"chmod", riscos_chmod},
362 {"utime", riscos_utime},
363 {"settype", riscos_settype},
364 {"getenv", riscos_getenv},
365 {"putenv", riscos_putenv},
366 {"delenv", riscos_delenv},
367 {"getenvdict", riscos_getenvdict,1},
368 {NULL, NULL} /* Sentinel */
373 void
374 initriscos()
376 PyObject *m, *d, *stat_m;
378 m = Py_InitModule("riscos", riscos_methods);
379 d = PyModule_GetDict(m);
381 /* Initialize riscos.error exception */
382 PyDict_SetItemString(d, "error", PyExc_OSError);
384 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
385 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);