blob: e9673677fbcebdd0b8b17649950f22c5134b522a [file] [log] [blame]
Zesstra984bde92017-01-29 22:19:52 +01001#include "/sys/files.h"
2
3#define PO efun::previous_object(0)
4
5public varargs string read_data(string file, int start, int anzahl)
6{
7 if (!stringp(file))
8 raise_error("Bad arg 1 to read_data(): expected 'string'.\n");
9
10 // Wenn Pfad nicht absolut, ist das nen Fehler, daher wird das nicht
11 // korrigiert.
12
13 // wenn kein /data/ vorn steht, wird es vorangestellt.
14 if (strstr(file,"/"LIBDATADIR"/") != 0)
15 {
16 file = "/"LIBDATADIR + file;
17 }
18 // read_file() nicht direkt rufen, sondern vorher als closure ans
19 // aufrufende Objekt binden. Sonst laeuft die Rechtepruefung in
20 // valid_write() im Master unter der Annahme, dass die simul_efun.c mit
21 // ihrer root id was will.
22 return funcall(bind_lambda(#'efun::read_file, previous_object()),
23 file, start, anzahl);
24}
25
26public varargs int write_data(string file, string str, int flags)
27{
28 if (!stringp(file))
29 raise_error("Bad arg 1 to write_data(): expected 'string'.\n");
30 if (!stringp(str))
31 raise_error("Bad arg 2 to write_data(): expected 'string'.\n");
32
33 // Wenn Pfad nicht absolut, ist das nen Fehler, daher wird das nicht
34 // korrigiert.
35
36 // wenn kein /data/ vorn steht, wird es vorangestellt.
37 if (strstr(file,"/"LIBDATADIR"/") != 0)
38 {
39 file = "/"LIBDATADIR + file;
40 }
41 // write_file() nicht direkt rufen, sondern vorher als closure ans
42 // aufrufende Objekt binden. Sonst laeuft die Rechtepruefung in
43 // valid_write() im Master unter der Annahme, dass die simul_efun.c mit
44 // ihrer root id was will.
45 return funcall(bind_lambda(#'efun::write_file, previous_object()),
46 file, str, flags);
47}
48
49// * Bei 50k Groesse Log-File rotieren
50varargs int log_file(string file, string txt, int size_to_break)
51{
52 mixed *st;
53 // Wenn file schon mit /log/ anfaengt, schreiben wir nicht noch eins
54 // davor.
55 if (strstr(file,"/"LIBLOGDIR"/") != 0)
56 {
57 file="/log/"+file;
58 }
59
60 // Achtung: es ist verfuehrerisch, diese Pruefung zu entfernen und
61 // stattdessen, den Aufruf von write_file() an den Aufrufer zu binden.
62 // Dies funktioniert aber nicht, weil log_file gesonderte Behandlung in
63 // valid_write() erfaehrt.
64 file=implode((efun::explode(file,"/")-({".."})),"/");
65 if (!funcall(bind_lambda(#'efun::call_other,PO),"secure/master",//')
66 "valid_write",file,geteuid(PO),"log_file",PO))
67 return 0;
68
Zesstraf1673762018-09-05 16:41:34 +020069 // pruefen, ob das Verzeichnis existiert - sonst anlegen
70 string dir=file[..strrstr(file,"/")-1];
71 if (file_size(dir) != -2) // FSIZE_DIR
72 {
73 if (!mkdirp(dir))
74 return 0;
75 }
76
Zesstra984bde92017-01-29 22:19:52 +010077 // Wenn zu gross, rotieren.
78 if ( size_to_break >= 0 & (
79 sizeof(st = get_dir(file,2) ) && st[0] >= (size_to_break|MAX_LOG_SIZE)))
80 catch(rename(file, file + ".old");publish); /* No panic if failure */
81
82 // Die Zugriffspruefung hier laeuft mit Rechten der simul_efuns...
83 // Rechtepruefung oben
84 return(write_file(file,txt));
85}
86
87#if !__EFUN_DEFINED__(copy_file)
88#define MAXLEN 50000
89public nomask int copy_file(string source, string dest)
90{
91
92 int ptr;
Zesstraa284f5c2019-09-27 16:14:00 +020093 bytes byte_seq;
Zesstra984bde92017-01-29 22:19:52 +010094
95 set_this_object(previous_object());
Zesstra2451a712020-08-27 22:14:15 +020096 if (!sizeof(source) || !sizeof(dest) || source==dest
97 || (file_size(source) < 0) // kein File?
98 || !master()->valid_read(source,
99 getuid(this_interactive()||previous_object()),
100 "read_file",previous_object())
101 || !master()->valid_write(dest,
102 getuid(this_interactive()||previous_object()),
103 "write_file",previous_object())
104 )
Zesstra984bde92017-01-29 22:19:52 +0100105 return 1;
Zesstra2451a712020-08-27 22:14:15 +0200106
Zesstra984bde92017-01-29 22:19:52 +0100107 switch (file_size(dest))
108 {
109 case -1:
110 break;
111 case -2:
112 if (dest[<1]!='/') dest+="/";
113 dest+=efun::explode(source,"/")[<1];
114 if (file_size(dest)==-2) return 1;
115 if (file_size(dest)!=-1) break;
116 default:
117 if (!rm(dest)) return 1;
118 break;
119 }
120 do
121 {
Zesstraa284f5c2019-09-27 16:14:00 +0200122 byte_seq = read_bytes(source, ptr, MAXLEN); ptr += MAXLEN;
123 if (!byte_seq) byte_seq="";
124 write_file(dest, byte_seq);
Zesstra984bde92017-01-29 22:19:52 +0100125 }
Zesstraa284f5c2019-09-27 16:14:00 +0200126 while(sizeof(byte_seq) == MAXLEN);
Zesstra984bde92017-01-29 22:19:52 +0100127 return 0;
128}
129#endif //!__EFUN_DEFINED__(copy_file)
130
131#undef PO
132