1 /* RISCOS module implementation */
3 #include "oslib/osfscontrol.h"
4 #include "oslib/osgbpb.h"
6 #include "oslib/osfile.h"
10 #include "structseq.h"
16 /*static PyObject *RiscosError;*/ /* Exception riscos.error */
18 static PyObject
*riscos_error(char *s
)
20 PyErr_SetString(PyExc_OSError
, s
);
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
)
34 if (!PyArg_Parse(args
, "s", &path1
)) return NULL
;
35 if (remove(path1
)) return PyErr_SetFromErrno(PyExc_OSError
);
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
);
48 static PyObject
*riscos_system(PyObject
*self
,PyObject
*args
)
50 if (!PyArg_Parse(args
, "s", &command
)) return NULL
;
51 return PyInt_FromLong(system(command
));
54 static PyObject
*riscos_chdir(PyObject
*self
,PyObject
*args
)
56 if (!PyArg_Parse(args
, "s", &path
)) return NULL
;
57 e
=xosfscontrol_dir(path
);
58 if(e
) return riscos_oserror();
63 static PyObject
*canon(char *path
)
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");
76 return riscos_oserror();
79 static PyObject
*riscos_getcwd(PyObject
*self
,PyObject
*args
)
80 { if(!PyArg_NoArgs(args
)) return NULL
;
84 static PyObject
*riscos_expand(PyObject
*self
,PyObject
*args
)
86 if (!PyArg_Parse(args
, "s", &path
)) return NULL
;
90 static PyObject
*riscos_mkdir(PyObject
*self
,PyObject
*args
)
93 if (!PyArg_ParseTuple(args
, "s|i", &path
, &mode
)) return NULL
;
94 e
=xosfile_create_dir(path
,0);
95 if(e
) return riscos_oserror();
100 static PyObject
*riscos_listdir(PyObject
*self
,PyObject
*args
)
101 { char *path
,buf
[256];
104 if (!PyArg_Parse(args
, "s", &path
)) return NULL
;
108 { e
=xosgbpb_dir_entries(path
,(osgbpb_string_list
*)buf
,
109 1,c
,256,0,&count
,&c
);
111 { Py_DECREF(d
);return riscos_oserror();
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;}
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" },
150 static PyStructSequence_Desc stat_result_desc
= {
151 "riscos.stat_result",
157 static PyTypeObject StatResultType
;
159 static PyObject
*riscos_stat(PyObject
*self
,PyObject
*args
)
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();
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
);
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()) {
208 static PyObject
*riscos_chmod(PyObject
*self
,PyObject
*args
)
212 attr
=(mode
&0x700)>>8;
214 if (!PyArg_Parse(args
, "(si)", &path
,(int*)&mode
)) return NULL
;
215 e
=xosfile_write_attr(path
,attr
);
216 if(e
) return riscos_oserror();
222 static PyObject
*riscos_utime(PyObject
*self
,PyObject
*args
)
228 if (!PyArg_ParseTuple(args
, "sO:utime", &path
, &arg
))
231 if (arg
== Py_None
) {
232 /* optional time values not given */
233 Py_BEGIN_ALLOW_THREADS
234 e
=xosfile_stamp(path
);
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)");
245 fileswitch_object_type obj_type
;
246 bits load_addr
, exec_addr
;
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
);
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
);
268 if(e
) return riscos_oserror();
275 static PyObject
*riscos_settype(PyObject
*self
,PyObject
*args
)
278 if (!PyArg_Parse(args
, "(si)", &path
,&type
))
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();
290 static PyObject
*riscos_getenv(PyObject
*self
,PyObject
*args
)
292 if(!PyArg_Parse(args
,"s",&name
)) return NULL
;
294 if(value
) return PyString_FromString(value
);
299 static PyObject
*riscos_putenv(PyObject
*self
,PyObject
*args
)
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");
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();
316 static PyObject
*riscos_delenv(PyObject
*self
,PyObject
*args
)
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();
325 static PyObject
*riscos_getenvdict(PyObject
*self
,PyObject
*args
)
331 if(!PyArg_ParseTuple(args
,"|s",&which
)) return NULL
;
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))
339 v
= PyString_FromString(value
);
340 if (v
== NULL
) continue;
341 PyDict_SetItemString(dict
, context
, v
);
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 */
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
);