1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import os,time,shutil,tempfile
16
17 UUCP_DIR = "/var/spool/uucp"
18 CMD_UUX = "/usr/bin/uux2"
19 CMD_UUCP = "/usr/bin/uucp2"
20 LOG_FILE = "/tmp/rapport.zephir"
21 LOCK = "/var/spool/uucp/lock"
22 IGNORE_LIST = ['.ssh','.Status','.Temp','.Received']
23
24 COMMANDS = {"zephir_client save_files":"Sauvegarde de configuration",
25 "zephir_client maj_auto":"Mise à jour",
26 "zephir_client maj_client":"Mise à jour de zephir-client",
27 "zephir_client configure":"Envoi de configuration",
28 "zephir_client reboot":"Redémarrage du serveur",
29 "zephir_client service_restart":"Redémarrage du service",
30 "zephir_client reconfigure":"Reconfiguration"}
31
32 UUCPError = 'UUCPError'
33
34
35 NUMBERS = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
36
37
39 result=0
40 digits = range(len(chaine))
41
42 digits.reverse()
43 for i in range(len(chaine)):
44
45 digit = NUMBERS.index(chaine[digits[i]])
46
47 result = result + digit * len(NUMBERS).__pow__(i)
48 return result
49
51 """wrapper d'uucp pour permettre la gestion des files dans zephir"""
52
54 """initialisation de l'objet"""
55 self.peers_ori=peers
56 self.pool={}
57 self._scan_pool()
58
60 """crée la liste d'attente en mémoire"""
61
62
63 if self.peers_ori is None:
64 peers = os.listdir(UUCP_DIR)
65 for peer in IGNORE_LIST:
66 if peer in peers:
67 peers.remove(peer)
68 else:
69 peers = self.peers_ori
70
71 for peer in peers:
72
73 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
74
75 lst={}
76 if os.path.isdir(peer_dir+"/C."):
77 for fic in os.listdir(peer_dir+"/C."):
78
79 date_creat = os.stat(peer_dir+"/C./"+fic)[-1]
80 f=file(peer_dir+"/C./"+fic)
81 l=f.read().strip().split('\n')[0]
82 f.close()
83
84
85
86
87 args=l.split()[1]
88 script=l.split()[5]
89 seq_number=convert_num(script[-4:])
90
91 type_cmd = "transfert"
92 if args.startswith("D.X"):
93 type_cmd = "execute"
94
95 f=file(peer_dir+"/D.X/"+script)
96 l=f.read().strip().split('\n')
97 f.close()
98 for line in l:
99 line = line.strip()
100 if line[:2] == "C ":
101 args = line[2:]
102
103 for command, label in COMMANDS.items():
104 if line[2:].startswith(command):
105 args = line[2:].replace(command, label)
106 break
107
108 lst[seq_number]=(type_cmd,args,script,fic,date_creat)
109
110 self.pool[peer]=lst
111
112
114 """met en place une commande distante"""
115 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
116
117 cmd = "%s -r '%s!%s >%s!%s'" % (CMD_UUX,peer,commande,peer,LOG_FILE)
118
119 timeout = 0
120 while os.path.isfile(LOCK):
121
122 timeout += 1
123
124 if timeout > 10:
125
126 raise UUCPError, "Problème d'accès concurrent, fichier %s présent" % LOCK
127 time.sleep(0.5)
128
129
130 lock=file(LOCK,"w")
131 lock.close()
132 try:
133
134 res=os.system(cmd)
135
136 if res == 0:
137
138 tempbuf=tempfile.mktemp()
139 os.system("/bin/ls -t %s" % peer_dir+"/C./ > %s" % tempbuf)
140 output=file(tempbuf)
141 res2=output.read()
142 output.close()
143 os.unlink(tempbuf)
144
145 filename = res2.split()[0]
146
147 f=file(peer_dir+"/C./"+filename)
148 l=f.read().strip().split('\n')[0]
149 f.close()
150 script = l.split()[5]
151
152 seq_num=convert_num(script[-4:])
153 if not self.pool.has_key(peer):
154 self.pool[peer]={}
155 self.pool[peer][seq_num]=("execute",commande,script,filename)
156
157 os.unlink(LOCK)
158 return seq_num
159 else:
160 os.unlink(LOCK)
161 raise Exception("uux2 a retourné une erreur")
162 except Exception,e:
163 os.unlink(LOCK)
164
165 raise UUCPError, """erreur lors de la préparation de l'exécution de %s : %s""" % (commande,str(e))
166
167 - def add_file(self,peer,fichier,destination="~"):
168 """prépare l'envoi d'un fichier"""
169 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
170
171 cmd = "%s -r %s %s\\!%s" % (CMD_UUCP,fichier,peer,destination)
172
173 timeout = 0
174 while os.path.isfile(LOCK):
175
176 timeout += 1
177
178 if timeout > 10:
179
180 raise UUCPError, "Problème d'accès concurrent, fichier %s présent" % LOCK
181 time.sleep(0.5)
182
183
184 lock=file(LOCK,"w")
185 lock.close()
186 try:
187
188 res=os.system(cmd)
189
190 if res == 0:
191
192 tempbuf=tempfile.mktemp()
193 os.system("/bin/ls -t %s" % peer_dir+"/C./ > %s" % tempbuf)
194 output=file(tempbuf)
195 res2=output.read()
196 output.close()
197 os.unlink(tempbuf)
198
199 filename = res2.split()[0]
200
201 f=file(peer_dir+"/C./"+filename)
202 l=f.read().strip().split('\n')[0]
203 f.close()
204 script = l.split()[5]
205
206 seq_num=convert_num(script[-4:])
207 if not self.pool.has_key(peer):
208 self.pool[peer]={}
209 self.pool[peer][seq_num]=("transfert",fichier,script,filename)
210
211 os.unlink(LOCK)
212 return 0
213 else:
214 os.unlink(LOCK)
215 raise UUCPError, """echec à l'exécution de uucp"""
216 except Exception,e:
217 os.unlink(LOCK)
218 raise UUCPError, """erreur lors de la préparation du transfert de %s : %s""" % (fichier,e)
219
221 """fonction interne qui liste les actions d'un type particulier"""
222 cmds = {}
223
224 for peer in peers:
225 cmds[peer] = []
226 if not self.pool.has_key(peer):
227 continue
228
229 numeros = self.pool[peer].keys()
230 numeros.sort()
231 for n in numeros:
232 action=self.pool[peer][n]
233
234 if action[0] == type_cmd:
235
236 cmds[peer].append((n,action[1]))
237 return cmds
238
240 """vérifie si il existe des commandes plus anciennes
241 que max_time pour un serveur donné (ou tous)
242 @param max_time: age maximum en seconde accepté pour une commande
243 retourne un dictionnaire {serveur:liste des ids de commande trop anciens}"""
244 dic_res = {}
245 if peer is not None:
246 peers=[peer]
247 else:
248 self._scan_pool()
249 peers=self.pool.keys()
250 for serveur in peers:
251 timeouts = []
252 if self.pool.has_key(serveur):
253 for seq_num, data in self.pool[serveur].items():
254 test_time = time.localtime(float(data[-1] + max_time))
255
256 if test_time < time.localtime():
257
258 timeouts.append((seq_num, time.ctime(data[-1])))
259 if timeouts != []:
260 dic_res[serveur] = timeouts
261 return dic_res
262
263
264
266 """renvoie la liste des commandes en attente"""
267 if peer is not None:
268 peers=[peer]
269 else:
270 self._scan_pool()
271 peers=self.pool.keys()
272 return self._create_liste("execute",peers)
273
275 """renvoie la liste des transferts en attente"""
276 if peer is not None:
277 peers=[peer]
278 else:
279 self._scan_pool()
280 peers=self.pool.keys()
281 return self._create_liste("transfert",peers)
282
284 """supprime une commande ou un transfert"""
285 type_cmd,fichier,script,filename,date_creat = self.pool[peer][int(num_cmd)]
286 peer_dir = os.path.abspath(UUCP_DIR+os.sep+peer)
287
288 timeout = 0
289 while os.path.isfile(LOCK):
290
291 timeout += 1
292
293 if timeout > 10:
294
295 raise UUCPError, "Problème d'accès concurrent, fichier %s présent" % LOCK
296 time.sleep(0.5)
297
298
299 lock=file(LOCK,"w")
300 lock.close()
301
302 try:
303 os.unlink(peer_dir+'/C./'+filename)
304 if type_cmd == "transfert":
305
306 os.unlink(peer_dir+'/D./'+script)
307 else:
308
309 os.unlink(peer_dir+'/D.X/'+script)
310
311 os.unlink(LOCK)
312 except:
313
314 os.unlink(LOCK)
315 raise UUCPError, "erreur lors de la suppression des fichiers"
316
317 del(self.pool[peer][int(num_cmd)])
318 return 0
319
320
321 - def flush(self,peers=None):
322 """supprime toute la file d'attente"""
323 if peers is None:
324 for i in os.listdir(UUCP_DIR):
325 if i not in IGNORE_LIST:
326 try:
327
328 if os.path.isdir(UUCP_DIR+os.sep+i):
329 shutil.rmtree(UUCP_DIR+os.sep+i)
330 self.pool[i]={}
331 except:
332 raise UUCPError, """erreur de suppression de la file d'attente de %s""" % i
333 else:
334 try:
335 for peer in peers:
336 if os.path.isdir(UUCP_DIR+os.sep+peer):
337 shutil.rmtree(UUCP_DIR+os.sep+peer)
338 self.pool[peer]={}
339 except:
340 raise UUCPError, """erreur de supression de la file d'attente"""
341 return 0
342
343 uucp_pool = UUCP()
344
345 if __name__ == '__main__':
346 peers = ["0210056X-1","0210056X-2","0210056X-3","0210056X-4","0210056X-5"]
347 uucp=UUCP(peers)
348 peer = ""
349 while not peer in peers:
350 peer = raw_input("\nvoir la file d'attente de : ")
351 print "\ncommandes :\n"
352 for cmd in uucp.list_cmd(peer)[peer]:
353 print " "+str(cmd)
354
355 print "\ntransferts :\n"
356 for cmd in uucp.list_files(peer)[peer]:
357 print " "+str(cmd)
358 print '\n'
359