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