blob: adcc1286bcac7c583b9caeae662569b2644b5de5 [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"
Guido van Rossumbd67d6f2001-10-27 21:16:16 +000010#include "structseq.h"
Guido van Rossum228d8072001-03-02 05:58:11 +000011
12#include <errno.h>
13
14static os_error *e;
15
Guido van Rossume877f8b2001-10-24 20:13:15 +000016/*static PyObject *RiscosError;*/ /* Exception riscos.error */
Guido van Rossum228d8072001-03-02 05:58:11 +000017
Guido van Rossume877f8b2001-10-24 20:13:15 +000018static PyObject *riscos_error(char *s)
19{
20 PyErr_SetString(PyExc_OSError, s);
21 return NULL;
Guido van Rossum228d8072001-03-02 05:58:11 +000022}
23
Guido van Rossume877f8b2001-10-24 20:13:15 +000024static PyObject *riscos_oserror(void)
25{
26 return riscos_error(e->errmess);
27}
28
Guido van Rossum228d8072001-03-02 05:58:11 +000029
30/* RISCOS file commands */
31
32static PyObject *riscos_remove(PyObject *self,PyObject *args)
33{ char *path1;
34 if (!PyArg_Parse(args, "s", &path1)) return NULL;
Guido van Rossume877f8b2001-10-24 20:13:15 +000035 if (remove(path1)) return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum228d8072001-03-02 05:58:11 +000036 Py_INCREF(Py_None);
37 return Py_None;
38}
39
40static PyObject *riscos_rename(PyObject *self,PyObject *args)
41{ char *path1, *path2;
42 if (!PyArg_Parse(args, "(ss)", &path1, &path2)) return NULL;
Guido van Rossume877f8b2001-10-24 20:13:15 +000043 if (rename(path1,path2)) return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum228d8072001-03-02 05:58:11 +000044 Py_INCREF(Py_None);
45 return Py_None;
46}
47
48static 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));
52}
53
54static 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;
61}
62
63static 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();
77}
78
79static PyObject *riscos_getcwd(PyObject *self,PyObject *args)
80{ if(!PyArg_NoArgs(args)) return NULL;
81 return canon("@");
82}
83
84static PyObject *riscos_expand(PyObject *self,PyObject *args)
85{ char *path;
86 if (!PyArg_Parse(args, "s", &path)) return NULL;
87 return canon(path);
88}
89
90static 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;
98}
99
100static 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();
112 }
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;}
117 }
118 if(c==-1) break;
119 }
120 return d;
121}
122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000123PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000124"stat_result: Result from stat or lstat.\n\n\
125This object may be accessed either as a tuple of\n\
126 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
127or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
128\n\
129RiscOS: The fields st_ftype, st_attrs, and st_obtype are also available.\n\
130\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000131See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000132
133static 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" },
Guido van Rossumbd67d6f2001-10-27 21:16:16 +0000146 { "st_obtype", "object type" },
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000147 { 0 }
148};
149
150static PyStructSequence_Desc stat_result_desc = {
Guido van Rossum14648392001-12-08 18:02:58 +0000151 "riscos.stat_result",
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000152 stat_result__doc__,
153 stat_result_fields,
154 13
155};
156
157static PyTypeObject StatResultType;
158
Guido van Rossum228d8072001-03-02 05:58:11 +0000159static PyObject *riscos_stat(PyObject *self,PyObject *args)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000160{
161 PyObject *v;
162 char *path;
Guido van Rossum228d8072001-03-02 05:58:11 +0000163 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");
174 }
175 if(ft!=-1) t=unixtime(ld,ex);
176 mode|=(at&7)<<6;
177 mode|=((at&112)*9)>>4;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000178
179 v = PyStructSequence_New(&StatResultType);
180
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,
Guido van Rossumbd67d6f2001-10-27 21:16:16 +0000198 PyInt_FromLong((long) ob)); /*object type*/
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000199
200 if (PyErr_Occurred()) {
201 Py_DECREF(v);
202 return NULL;
203 }
204
205 return v;
Guido van Rossum228d8072001-03-02 05:58:11 +0000206}
207
208static 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;
219}
220
Guido van Rossume877f8b2001-10-24 20:13:15 +0000221
Guido van Rossum228d8072001-03-02 05:58:11 +0000222static PyObject *riscos_utime(PyObject *self,PyObject *args)
Guido van Rossume877f8b2001-10-24 20:13:15 +0000223{
224 char *path;
225 long atime, mtime;
226 PyObject* arg;
227
228 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
229 return NULL;
230
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();
237 }
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;
242 }
243 else {
244 /* catalogue info*/
245 fileswitch_object_type obj_type;
246 bits load_addr, exec_addr;
247 int size;
248 fileswitch_attr attr;
249
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();
255
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");
259
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();
263
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();
269 }
270
Guido van Rossum228d8072001-03-02 05:58:11 +0000271 Py_INCREF(Py_None);
272 return Py_None;
273}
274
275static 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();
283 }
284 e=xosfile_set_type(path,type);
285 if(e) return riscos_oserror();
286 Py_INCREF(Py_None);
287 return Py_None;
288}
289
290static 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;
297}
298
299static 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;
314}
315
316static 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;
323}
324
325static 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);
343 }
344 return dict;
345}
346
347static PyMethodDef riscos_methods[] = {
348
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 */
369};
370
371
372
373void
374initriscos()
375{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000376 PyObject *m, *d, *stat_m;
Guido van Rossum228d8072001-03-02 05:58:11 +0000377
378 m = Py_InitModule("riscos", riscos_methods);
379 d = PyModule_GetDict(m);
380
381 /* Initialize riscos.error exception */
Guido van Rossume877f8b2001-10-24 20:13:15 +0000382 PyDict_SetItemString(d, "error", PyExc_OSError);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000383
384 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
385 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum228d8072001-03-02 05:58:11 +0000386}