1 /* matos.c
2  * Copyright (C) 2004, 2005 Sylvain Cresto <scresto@gmail.com>
3  *
4  * This file is part of graveman!
5  *
6  * graveman! is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or
9  * (at your option) any later version.
10  *
11  * graveman! is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with program; see the file COPYING. If not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19  * MA 02111-1307, USA.
20  *
21  * URL: http://www.nongnu.org/graveman/
22  *
23  */
24 
25 /* initialisation des devices */
26 
27 #include "graveman.h"
28 
29 GSList *Glistdrives = NULL;
30 
find_drive(gchar * Aident)31 Tdriveinfo *find_drive(gchar *Aident) {
32   GSList *Lcur, *Lcurdev;
33   Tdriveinfo *Ldrive;
34 
35   for (Lcur = Glistdrives; Lcur; Lcur = g_slist_next(Lcur)) {
36     Ldrive = (Tdriveinfo *)Lcur->data;
37 
38     for (Lcurdev = Ldrive->dev; Lcurdev; Lcurdev = g_slist_next(Lcurdev)) {
39 
40   _DEB("om compare [%s] et [%s]\n", Aident, (gchar *)Lcurdev->data);
41       if (!strcmp(Aident, (gchar *)Lcurdev->data)) {
42         _DEB("ici GL vitesse => %d\n", Ldrive->vitesse);
43         return Ldrive;
44       }
45     }
46   }
47 
48   return NULL;
49 }
50 
51 /* ajout d'un lecteur a la liste des lecteurs */
append_this_drive(Tdriveinfo * Adrive)52 void append_this_drive(Tdriveinfo *Adrive) {
53   Glistdrives=g_slist_append(Glistdrives, Adrive);
54 }
55 
56 /* liberation de la zone memoire occupe par une structure lecteur */
free_this_drive(Tdriveinfo * Adrive)57 void free_this_drive(Tdriveinfo *Adrive) {
58   GSList *Lcur;
59   if (g_slist_length(Adrive->dev)) {
60     for (Lcur = Adrive->dev; Lcur; Lcur = g_slist_next(Lcur)) {
61       g_free((gchar *)Lcur->data);
62     }
63     g_slist_free(Adrive->dev);
64   }
65   if (g_slist_length(Adrive->bus)) {
66     for (Lcur = Adrive->bus; Lcur; Lcur = g_slist_next(Lcur)) {
67       g_free((gchar *)Lcur->data);
68     }
69     g_slist_free(Adrive->bus);
70   }
71 
72   g_free(Adrive->name);
73 }
74 
free_drives(gboolean Aremovemanu)75 void free_drives(gboolean Aremovemanu)
76 {
77   GSList *Ltmp = Glistdrives, *Lcurlist;
78   gboolean Ldonotdel;
79   Tdriveinfo *Lcur;
80 
81   while (Ltmp) {
82     Lcurlist = Ltmp;
83     Lcur = (Tdriveinfo *)Ltmp->data;
84 
85     Ldonotdel = (Lcur->manual == TRUE && Aremovemanu==FALSE);
86 
87     Ltmp = g_slist_next(Ltmp);
88 
89     if (Ldonotdel == FALSE) {
90       free_this_drive((Tdriveinfo *)Lcurlist->data);
91 
92       Glistdrives = g_slist_delete_link(Glistdrives, Lcurlist);
93     }
94   }
95 
96   if (g_slist_length(Glistdrives)==0) Glistdrives = NULL;
97 }
98 
matos_get_current_matos(gboolean * Areadcd,gboolean * Awritecdr,gboolean * Awritecdrw,gboolean * Areaddvd,gboolean * Awritedvd)99 void matos_get_current_matos(gboolean *Areadcd, gboolean *Awritecdr, gboolean *Awritecdrw, gboolean *Areaddvd, gboolean *Awritedvd)
100 {
101   GSList *Lcur;
102   Tdriveinfo *Ldrive;
103 
104   if (Areadcd) *Areadcd = FALSE;
105   if (Awritecdr) *Awritecdr = FALSE;
106   if (Awritecdrw) *Awritecdrw = FALSE;
107   if (Areaddvd) *Areaddvd = FALSE;
108   if (Awritedvd) *Awritedvd = FALSE;
109 
110   for (Lcur = Glistdrives; Lcur; Lcur = g_slist_next(Lcur)) {
111     Ldrive = (Tdriveinfo *)Lcur->data;
112 
113     if (DRIVE_READER(Ldrive) && Areadcd) *Areadcd = TRUE;
114     if (DRIVE_WRITER(Ldrive) && Awritecdr) *Awritecdr = TRUE;
115     if (DRIVE_CDRW_WRITER(Ldrive) && Awritecdrw) *Awritecdrw = TRUE;
116     if (DRIVE_DVDREADER(Ldrive) && Areaddvd) *Areaddvd = TRUE;
117     if (DRIVE_DVDWRITER(Ldrive) && Awritedvd) *Awritedvd = TRUE;
118   }
119 }
120 
matos_insert_or_update_drive(gchar * Adev,gchar * Amarque,gchar * Amodel,gchar * Aquoi,Tsearchdrive * Adrivedesc)121 void matos_insert_or_update_drive(gchar *Adev, gchar *Amarque, gchar *Amodel, gchar *Aquoi, Tsearchdrive *Adrivedesc)
122 {
123   /* on commence par construire l'identifiant */
124   gchar *Lident = g_strdup_printf("%s %s %s", Amarque, Amodel, Aquoi);
125   GSList *Lcur = NULL;
126   Tdriveinfo *Ldrive;
127 
128   for (Lcur = Glistdrives; Lcur; Lcur = g_slist_next(Lcur)) {
129     Ldrive = (Tdriveinfo *)Lcur->data;
130 
131     if (!strcmp(Ldrive->name, Lident) && strcmp((gchar *)g_slist_last(Ldrive->bus)->data, Adrivedesc->bus)) {
132 _DEB("mise a jour du lecteur [%s]\n", Lident);
133       /* oui ce lecteur existe deja, c'est donc lui qui l'on va mettre a jour */
134       break;
135     }
136   }
137 
138   if (!Lcur) {
139     /* le lecteur n'existe pas encore, on l'ajoute a la liste */
140 
141     Ldrive = g_malloc0(sizeof(Tdriveinfo));
142     Ldrive->name = Lident;
143 
144     Glistdrives = g_slist_append(Glistdrives, Ldrive);
145 _DEB("nouveau lecteur [%s]\n", Lident);
146   } else {
147     g_free(Lident);
148   }
149 
150 _DEB("le bus en question [%s] = [%s]\n", Adrivedesc->bus, Adev);
151   Ldrive->bus = g_slist_append(Ldrive->bus, g_strdup(Adrivedesc->bus));
152   Ldrive->dev = g_slist_append(Ldrive->dev,
153       g_strdup_printf("%s%s", Adrivedesc->useline,
154         strcmp(Adrivedesc->bus, "IDE") && strncmp(Adrivedesc->bus, IDENT_SCSI, strlen(IDENT_SCSI)) ?
155           Adev : ""));
156 }
157 
158 /* operation de copie */
burn_copy(Tgrave * Ag,GError ** Aerror)159 gboolean burn_copy(Tgrave *Ag, GError **Aerror)
160 {
161   Tdriveinfo *Lsource = matos_get_drive_info(Ag, "srccopycombo");
162   Tdriveinfo *Lgraveur = matos_get_drive_info(Ag, "dstcopycombo");
163   GtkEntry *Llecteuriso = GTK_ENTRY(sc_grave_get_widget(Ag, "srccopybtnvalue"));
164   GtkEntry *Lgraveuriso = GTK_ENTRY(sc_grave_get_widget(Ag, "dstcopybtnvalue"));
165   gchar *Ltxt;
166   gboolean Lstatus;
167   gboolean Loperationstatus = FALSE;
168   gint Ltodo = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sc_grave_get_widget(Ag, "nbrcdcopy")));
169   gint Ldone = 1;
170   gchar Ltmpdir[MAXPATHLEN]="";
171   gchar Liso[MAXPATHLEN]="";
172   const gchar *Lptriso;
173 _DEB("DEBUT COPIE !!");
174 
175   if (!Lsource && !Lgraveur) {
176     g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_MODE,
177       _("Cannot duplicate an iso image to an another iso image with graveman, just copy this file !"));
178     return FALSE;
179   }
180 
181   /* referecement variables */
182   sc_grave_set_data(Ag, &Ltodo, "todo"); /* a faire */
183   sc_grave_set_data(Ag, &Ldone, "done"); /* fais */
184   sc_grave_set_data(Ag, &Loperationstatus, "operationstatus"); /* resultat de l'operation */
185   sc_grave_set_data(Ag, &Ltmpdir, "tmpdir"); /* repertoire temporraire */
186   sc_grave_set_data(Ag, Aerror, "gerror");  /* pointeur retour des erreurs */
187 
188   if (!Lsource) {
189     /* copie d'une image vers un cd, on utilise cdrecord */
190     Lptriso = gtk_entry_get_text(Llecteuriso);
191     Ltxt = _FILENAME(Lptriso);
192     g_strlcpy(Liso, Ltxt, MAXPATHLEN-1);
193     g_free(Ltxt);
194 
195     /* on test si on a bien acces au fichier iso source */
196     if (!*Liso) {
197       g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA,
198           _("A valid iso image location is required in the \"Duplicate from\" field."));
199       Lstatus = FALSE;
200     } else if (access(Liso, R_OK + F_OK)==-1) {
201       g_set_error(Aerror, G_FILE_ERROR, g_file_error_from_errno(errno), "%s:%s\n%s",
202           _("Cannot read iso image source file"),
203           Liso, g_strerror(errno));
204       Lstatus = FALSE;
205     } else {
206       sc_grave_set_data(Ag, &Liso, "iso"); /* image iso */
207 
208       Lstatus = burn_from_image("copy", Ag, Aerror);
209       Lstatus = burn_iso2dvd(Ag, Aerror);
210       sc_grave_del_data(Ag, "iso");
211     }
212   } else if (!Lgraveur) {
213     /* copie d'un cd vers une image, on utilise readcd */
214     struct stat Lfstat;
215     Lptriso = gtk_entry_get_text(Lgraveuriso);
216     Ltxt = _FILENAME(Lptriso);
217     g_strlcpy(Liso, Ltxt, MAXPATHLEN-1);
218     g_free(Ltxt);
219     /* si le fichier existe deja on demande confirmatation avant de l'ecraser */
220     Ltxt = NULL;
221     if (!*Liso) {
222       g_set_error(Aerror, GRAVEMAN_ERROR, _ERR_INAPPROPRIATE_DATA,
223             _("A valid iso image location is required the \"Duplicate to\" field."));
224       Lstatus = FALSE;
225     } else if (stat(Liso, &Lfstat) == -1) {
226       if (errno != ENOENT) Ltxt = _("Cannot access file");
227     } else if (access(Liso, W_OK)==-1) {
228       Ltxt = _("Cannot overwrite file");
229     }
230     if (Ltxt) {
231       g_set_error(Aerror, G_FILE_ERROR, g_file_error_from_errno(errno), "%s: %s\n%s",
232           Ltxt, Liso, g_strerror(errno));
233       Lstatus = FALSE;
234     } else {
235       Ltodo = 1;
236       sc_grave_set_data(Ag, &Liso, "iso"); /* image iso */
237       Lstatus = make_image(Ag, Aerror);
238       sc_grave_del_data(Ag, "iso");
239     }
240   } else {  /* copie d'un cd a un autre, on utilise cdrdao */
241     /* on ajoute une tache pour la lecture,
242      * si il y a simulation alors ajoute une tache a faire */
243 //    Ltodo = Ltodo + 1 + (Lsimul == TRUE ? 1 : 0);
244 
245       /* copie d'un cd vers un cd
246        * on passe quand meme vers une image temporraire pour le moment,
247        * c'est trop le bordel sinon ! */
248 _DEB("DEBUT COPIE !!");
249     g_snprintf(Ltmpdir, MAXPATHLEN-1, "%s/%s", conf_get_string_def("tmpdir", "/tmp"), "gravemanXXXXXX");
250 
251     if (!mkdtemp(Ltmpdir)) {
252       g_set_error(Aerror, G_FILE_ERROR, g_file_error_from_errno(errno), "%s %s: %s",
253               _("Cannot create directory"), Ltmpdir, g_strerror(errno));
254       *Ltmpdir = 0;
255       Lstatus = FALSE;
256     } else {
257       g_snprintf(Liso, MAXPATHLEN-1, "%s/tmpiso.bin", Ltmpdir);
258 
259       sc_grave_set_data(Ag, &Liso, "iso"); /* image iso */
260 
261       /* copie du cd avec monsieur cdrdao */
262       Lstatus = copycd(Ag, Aerror);
263 
264 
265       /* on copie donc vers l'iso
266       Lstatus = make_image(Ag, Aerror);
267       if (Lstatus == TRUE && *Labort == FALSE) {
268         * et maintenant dans le sens inverse si tout va toujours bien *
269         Ldone++;
270 
271         * si le lecteur et le graveur sont les meme alors on demande a l'utilisateur
272          * de changer de CD.. ! *
273         if (!strcmp(Lsrc, Ldst)) {
274           gint Lrep;
275           GtkWidget *Lconfirm = gtk_message_dialog_new(NULL,
276                                               GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
277                                               GTK_BUTTONS_YES_NO,
278                  _("Reading is finished, now you should insert a CD-R, do you want to continue operation ?"));
279 
280           * on eject le CD *
281           eject_cd(Lsrc, NULL);
282 
283           Lrep = gtk_dialog_run(GTK_DIALOG(Lconfirm));
284           gtk_widget_destroy(Lconfirm);
285           if (Lrep == GTK_RESPONSE_NO) {
286             * si c'est non alors on arrete *
287             *Labort = TRUE;
288             Lstatus = TRUE;
289           }
290         }
291 
292         if (Lstatus == TRUE && *Labort == FALSE) {
293           Lstatus = burn_from_image("copy", Ag, Aerror);
294         }
295       } */
296       sc_grave_del_data(Ag, "iso");
297 
298       deltempdir(Ltmpdir);
299       *Ltmpdir = 0;
300     }
301   }
302 
303   sc_grave_del_data(Ag, "todo");
304   sc_grave_del_data(Ag, "done");
305   sc_grave_del_data(Ag, "operationstatus");
306   sc_grave_del_data(Ag, "tmpdir");
307   sc_grave_del_data(Ag, "gerror");
308 
309   return Lstatus;
310 }
311 
312 /* operation gravure cd de donnee */
burn_data(Tgrave * Ag,GError ** Aerror)313 gboolean burn_data(Tgrave *Ag, GError **Aerror)
314 {
315   gint Ltodo = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sc_grave_get_widget(Ag, "nbrcddata")));
316   gboolean Lsimul = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sc_grave_get_widget(Ag, "datasimul")));
317   GtkEntry *Lgraveuriso = GTK_ENTRY(sc_grave_get_widget(Ag, "dstdatabtnvalue"));
318   Tdriveinfo *Lgraveur = matos_get_drive_info(Ag, "dstdatacombo");
319   gboolean *Labort = sc_grave_get_data(Ag, "gabort");
320   gint Ldone = 1;
321   gchar Ltmpdir[MAXPATHLEN] = "";
322   gchar *Lextrapara = NULL;
323   gchar Liso[MAXPATHLEN] = "";
324   gchar *Ltmp;
325   gboolean Loperationstatus = FALSE;
326   gboolean Lstatus;
327 
328   sc_grave_set_data(Ag, &Ltodo, "todo"); /* a faire */
329   sc_grave_set_data(Ag, &Ldone, "done"); /* fais */
330   sc_grave_set_data(Ag, &Loperationstatus, "operationstatus"); /* resultat de l'operation */
331   sc_grave_set_data(Ag, Aerror, "gerror");  /* pointeur retour des erreurs */
332   sc_grave_set_data(Ag, &Ltmpdir, "tmpdir"); /* repertoire temporraire */
333 
334   /* on retourne dans ltmp le nom du repertoire temporraire utilise pour
335    * l'operation */
336   Lstatus = preparedata(Ag, Aerror);
337 
338   if (Lgraveur) {
339     g_snprintf(Liso, MAXPATHLEN-1, "%s.iso", Ltmpdir);
340     Ltodo+=(Lsimul ? 2 : 1); /* + 1 pour l'ecriture de l'image iso et 1 pour la simulation */
341   } else {
342     Ltmp = _FILENAME(gtk_entry_get_text(Lgraveuriso));
343     g_strlcpy(Liso, Ltmp, MAXPATHLEN-1);
344     g_free(Ltmp);
345     Ltodo = 1;
346   }
347 
348   sc_grave_set_data(Ag, &Liso, "iso"); /* image iso */
349   if (Lstatus && *Labort==FALSE) {
350     Lextrapara = make_image_getextrapara(Ag, "data");
351     sc_grave_set_data(Ag, Lextrapara, "extrapara"); /* parametres supplementaires */
352     Lstatus = make_iso(Ag, Aerror);
353     sc_grave_del_data(Ag, "extrapara");
354     g_free(Lextrapara);
355     if (Lgraveur && Lstatus && *Labort==FALSE) {
356       /* ici il faut appeler cdrecord ! */
357       Lextrapara = burn_data_getextrapara(Ag);
358       sc_grave_set_data(Ag, Lextrapara, "extrapara"); /* parametres supplementaires */
359       Lstatus = burn_from_image("data", Ag, Aerror);
360       sc_grave_del_data(Ag, "extrapara");
361       g_free(Lextrapara);
362     }
363   }
364 
365   cleandata(Ag, NULL);
366 
367   if (Lgraveur && *Liso
368       && g_file_test(Liso, G_FILE_TEST_EXISTS + G_FILE_TEST_IS_REGULAR)==TRUE) {
369     unlink(Liso);
370   }
371 
372   sc_grave_del_data(Ag, "todo");
373   sc_grave_del_data(Ag, "done");
374   sc_grave_del_data(Ag, "tmpdir");
375   sc_grave_del_data(Ag, "operationstatus");
376   sc_grave_del_data(Ag, "gerror");
377   sc_grave_del_data(Ag, "iso");
378 
379   return Lstatus;
380 }
381 
382 /* operation gravure cd audio */
burn_audio(Tgrave * Ag,GError ** Aerror)383 gboolean burn_audio(Tgrave *Ag, GError **Aerror)
384 {
385   GtkTreeModel *Ltreemodel = gtk_tree_view_get_model(GTK_TREE_VIEW(sc_grave_get_widget(Ag, "LISTEAUDIO")));
386 
387   gint Ltodo = gtk_tree_model_iter_n_children(Ltreemodel, NULL);
388   gint Ldone = 0;
389   gchar Ltmpdir[MAXPATHLEN] = "";
390   gboolean Lstatus, Loperationstatus = FALSE;
391 
392   sc_grave_set_data(Ag, &Ltodo, "todo"); /* a faire */
393   sc_grave_set_data(Ag, &Ldone, "done"); /* fais */
394   sc_grave_set_data(Ag, &Loperationstatus, "operationstatus"); /* resultat de l'operation */
395   sc_grave_set_data(Ag, Aerror, "gerror");  /* pointeur retour des erreurs */
396   sc_grave_set_data(Ag, &Ltmpdir, "tmpdir"); /* repertoire temporraire */
397 
398   Lstatus = preparetrack(Ag, Aerror);
399 
400   if (Lstatus == TRUE) {
401     Ldone = 1;
402 
403     Lstatus = gravepiste(Ag, Aerror);
404   }
405 
406   if (*Ltmpdir) {
407     _DEB("on free tmpdir !");
408     deltempdir(Ltmpdir);
409   }
410 
411   sc_grave_del_data(Ag, "todo");
412   sc_grave_del_data(Ag, "done");
413   sc_grave_del_data(Ag, "tmpdir");
414   sc_grave_del_data(Ag, "operationstatus");
415   sc_grave_del_data(Ag, "gerror");
416 
417   return Lstatus ? TRUE : FALSE;
418 }
419 
420 /* on efface le repertoire temporraire */
deltempdir(gchar * Ldirpath)421 gboolean deltempdir(gchar *Ldirpath)
422 {
423   gchar *Lfullname;
424   GDir *Ldir;
425   const gchar *Lunfic;
426 
427   if (!Ldirpath || !*Ldirpath) return TRUE;
428 
429   Ldir = g_dir_open(Ldirpath, 0, NULL);
430   if (!Ldir) {
431     g_warning("erreur lors de l'ouverture de [%s]: %s\n", Ldirpath, strerror(errno));
432     return FALSE;
433   }
434 
435   while ((Lunfic = g_dir_read_name(Ldir))) {
436     if (!strcmp(Lunfic, ".") || !strcmp(Lunfic, "..")) continue;
437 
438     Lfullname = g_strdup_printf("%s/%s", Ldirpath, Lunfic);
439 
440     if (g_file_test(Lfullname, G_FILE_TEST_IS_DIR)) {
441       /* on vide le repertoire avant */
442       if (FALSE==deltempdir(Lfullname)) return FALSE;
443     } else {
444       if (unlink(Lfullname)==-1) {
445         _WARN("erreur lors de la suppresion de [%s]\n", Lfullname);
446       }
447     }
448 
449     g_free(Lfullname);
450   }
451 
452   g_dir_close(Ldir);
453 
454   _DEB("on efface => %s\n", Ldirpath);
455   if (rmdir(Ldirpath)==-1) {
456     _WARN("erreur lors de la suppresion du repertoire [%s]: %s\n", Ldirpath, strerror(errno));
457     return FALSE;
458   }
459 _DEB("ok fin efface");
460   return TRUE;
461 }
462 
463 /* retourne le type d'un peripherique */
put_devicelabel(Tdriveinfo * Adrive,gchar * Abuf,gint Asizemax)464 void put_devicelabel(Tdriveinfo *Adrive, gchar *Abuf, gint Asizemax) {
465   if (DRIVE_DVDWRITER(Adrive)) {
466     g_strlcpy(Abuf, _("DVD Recorder"), Asizemax);
467   } else if (DRIVE_WRITER(Adrive)) {
468     g_strlcpy(Abuf, _("CD Recorder"), Asizemax);
469   } else if (DRIVE_DVDREADER(Adrive)) {
470     g_strlcpy(Abuf, _("DVD Reader"), Asizemax);
471   } else if (DRIVE_READER(Adrive)) {
472     g_strlcpy(Abuf, _("CD Reader"), Asizemax);
473   } else {
474     g_strlcpy(Abuf, _("Other device"), Asizemax);
475   }
476 }
477 
478 /*extern Tdriveinfo *get_drive_cmb(GtkComboBox *Acombo)
479 {
480   GtkTreeModel *Lmodel = gtk_combo_box_get_model(GTK_COMBO_BOX(Acombo));
481   GtkTreeIter Liter;
482   gint Lvalue = -1;
483   if (!gtk_combo_box_get_active_iter(Acombo, &Liter)) return NULL;
484 
485   gtk_tree_model_get(Lmodel, &Liter, 3, &Lvalue, -1);
486 
487   return (Tdriveinfo *) g_slist_nth_data(Glistdrives, Lvalue);
488 }*/
489 
490 /* operation gravure dcd de donnee */
burn_dvddata(Tgrave * Ag,GError ** Aerror)491 gboolean burn_dvddata(Tgrave *Ag, GError **Aerror)
492 {
493   gint Ltodo = gtk_spin_button_get_value(GTK_SPIN_BUTTON(sc_grave_get_widget(Ag, "nbrdvddata")));
494   gboolean Lsimul = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sc_grave_get_widget(Ag, "dvddatasimul")));
495   GtkEntry *Lgraveuriso = GTK_ENTRY(sc_grave_get_widget(Ag, "dstdvddatabtnvalue"));
496   Tdriveinfo *Lgraveur = matos_get_drive_info(Ag, "dstdvddatacombo");
497   gint Ldone = 1;
498   gchar Ltmpdir[MAXPATHLEN] = "";
499   gchar *Lextrapara = NULL;
500   gchar *Ltmp;
501   gchar Liso[MAXPATHLEN] = "";
502   gboolean Loperationstatus = FALSE;
503   gboolean Lstatus;
504 
505   sc_grave_set_data(Ag, &Ltodo, "todo"); /* a faire */
506   sc_grave_set_data(Ag, &Ldone, "done"); /* fais */
507   sc_grave_set_data(Ag, &Loperationstatus, "operationstatus"); /* resultat de l'operation */
508   sc_grave_set_data(Ag, Aerror, "gerror");  /* pointeur retour des erreurs */
509   sc_grave_set_data(Ag, &Ltmpdir, "tmpdir"); /* repertoire temporraire */
510 
511   /* on retourne dans ltmp le nom du repertoire temporraire utilise pour
512    * l'operation */
513   Lstatus = preparedata(Ag, Aerror);
514 
515   Lextrapara = make_image_getextrapara(Ag, "dvddata");
516   sc_grave_set_data(Ag, Lextrapara, "extrapara"); /* parametres supplementaires */
517 
518   if (Lgraveur) {
519     if (Lsimul) Ltodo++; /* 1 pour la simulation */
520 
521     Lstatus = burn_data2dvd(Ag, Aerror);
522   } else {
523     Ltmp = _FILENAME(gtk_entry_get_text(Lgraveuriso));
524     g_strlcpy(Liso, Ltmp, MAXPATHLEN-1);
525     g_free(Ltmp);
526     Ltodo = 1;
527     sc_grave_set_data(Ag, &Liso, "iso"); /* image iso */
528     Lstatus = make_iso(Ag, Aerror);
529     sc_grave_del_data(Ag, "iso");
530   }
531   sc_grave_del_data(Ag, "extrapara");
532   g_free(Lextrapara);
533 
534   cleandata(Ag, NULL);
535 
536   sc_grave_del_data(Ag, "todo");
537   sc_grave_del_data(Ag, "done");
538   sc_grave_del_data(Ag, "tmpdir");
539   sc_grave_del_data(Ag, "operationstatus");
540   sc_grave_del_data(Ag, "gerror");
541 
542   return Lstatus;
543 }
544 
get_media_label(gint Atypecd,gchar * Abuf,gint Alen)545 gchar* get_media_label(gint Atypecd, gchar *Abuf, gint Alen) {
546   *Abuf = 0;
547 
548   if ((Atypecd & _MEDIA_TITLE_BLANKORAPPENDABLE) == _MEDIA_TITLE_BLANKORAPPENDABLE) {
549     g_snprintf(Abuf, Alen, _("an empty or appendable CDR/RW"));
550   } else if (((Atypecd & _MEDIA_DVDP_RW) == _MEDIA_DVDP_RW) || ((Atypecd & _MEDIA_DVDM_RW) == _MEDIA_DVDM_RW)) {
551     g_snprintf(Abuf, Alen, _("a DVDRW"));
552   } else if ((Atypecd & _MEDIA_TITLE_DVDRew) == _MEDIA_TITLE_DVDRew) {
553     g_snprintf(Abuf, Alen, _("an empty or appendable DVDR/RW"));
554   } else if (((Atypecd & _MEDIA_DVDR_P) == _MEDIA_DVDR_P) || ((Atypecd & _MEDIA_DVDR_M) == _MEDIA_DVDR_M)) {
555     g_snprintf(Abuf, Alen, _("a DVDR"));
556   } else if ((Atypecd & _MEDIA_DVD) == _MEDIA_DVD) {
557     g_snprintf(Abuf, Alen, _("a DVD"));
558   } else if ((Atypecd & _MEDIA_CDRW) == _MEDIA_CDRW) {
559     g_snprintf(Abuf, Alen, _("a CDRW"));
560   } else if ((Atypecd & _MEDIA_CDR) == _MEDIA_CDR) {
561     g_snprintf(Abuf, Alen, _("a CDR"));
562   } else if ((Atypecd & _MEDIA_CD) == _MEDIA_CD) {
563     g_snprintf(Abuf, Alen, _("a CD"));
564   } else if (Atypecd == _MEDIA_NONE) {
565     g_snprintf(Abuf, Alen, _("no media"));
566   }
567 
568   return Abuf;
569 }
570 
set_waitwindow_title(gboolean Ainsert,gint Atypecd,gint Acurrent,Tgrave * Awaitg)571 void set_waitwindow_title(gboolean Ainsert, gint Atypecd, gint Acurrent, Tgrave *Awaitg)
572 {
573   gchar Lcd[_BUF_SIZE];
574   gchar Ltitle[_BUF_SIZE];
575   Tdriveinfo *Ldevice = (Tdriveinfo *)sc_grave_get_data(Awaitg, "device1");
576   GtkLabel *Llabel = GTK_LABEL(sc_grave_get_widget(Awaitg, "label1"));
577   *Ltitle=0;
578 
579   get_media_label(Atypecd, Lcd, sizeof(Lcd)-1);
580 
581   if (Ainsert) {
582     g_snprintf(Ltitle, sizeof(Ltitle)-1, _("Please insert %s in drive %s to continue..."), Lcd, Ldevice->name);
583   } else {
584     g_snprintf(Ltitle, sizeof(Ltitle)-1, _("Ok there is %s in drive %s."), Lcd, Ldevice->name);
585   }
586   gtk_label_set_text(Llabel, Ltitle);
587 
588   if (Ainsert) {
589     Llabel = GTK_LABEL(sc_grave_get_widget(Awaitg, "label2"));
590     g_snprintf(Ltitle, sizeof(Ltitle)-1, _("Currently: %s"),
591         Acurrent > -1 ?  get_media_label(Acurrent, Lcd, sizeof(Lcd)-1) : _("Initialization..."));
592     gtk_label_set_text(Llabel, Ltitle);
593   }
594 }
595 
596 
597 /* attente que l'utilisateur ai inser� le/les cd qui va bien */
callback_waiting_for_user(gpointer Adata)598 gboolean callback_waiting_for_user(gpointer Adata)
599 {
600   Tgrave *Lg = (Tgrave *)Adata;
601   gint *Lcont = (gint *)sc_grave_get_data(Lg, "cont");
602   gint *Ldetect = NULL;
603   GSList *Lrequis, *Lcur;
604   Tdriveinfo *Ldrive = NULL;
605   gint *Lmediatitle;
606   gint Lmedialu = _MEDIA_NONE;
607   gint Lmediatest;
608   gboolean Lstatusmedia = TRUE;
609   gboolean *Linitdisp = (gboolean *) sc_grave_get_data(Lg, "initdisp");
610 
611   Ldrive = sc_grave_get_data(Lg, "device1");
612   if (!Ldrive) return TRUE;
613   Lrequis = (GSList *) sc_grave_get_data(Lg, "devicerequis1");
614   Ldetect = (gint *) sc_grave_get_data(Lg, "detect1");
615   Lmediatitle = (gint *)sc_grave_get_data(Lg, "mediatitle1");
616 
617   if (Linitdisp && *Linitdisp) {
618     set_waitwindow_title(Lstatusmedia, *Lmediatitle, -1, Lg);
619     gtk_widget_show(GTK_WIDGET(sc_grave_get_data(Lg, "window")));
620     gdk_flush ();
621     *Linitdisp = FALSE;
622   }
623   matos_umount_device(Ldrive, NULL);
624 
625  _DEB("le premier avant le dvd [%d]", Lmedialu);
626   Lmedialu += get_dvdinfo(Lg, Ldrive, NULL);
627 
628  _DEB("le deuxieme avant le cd [%d]", Lmedialu);
629   if (Lmedialu == _MEDIA_NONE) {
630     Lmedialu += get_cdinfo(Lg, Ldrive, NULL);
631   }
632 
633  _DEB("[%d] la troisieme apres tout [%d]", Ldetect ? 1 : 0, Lmedialu);
634   if (Ldetect) *Ldetect = Lmedialu;
635 
636   for (Lcur = Lrequis; Lcur; Lcur = g_slist_next(Lcur)) {
637     Lmediatest = (int ) Lcur->data;
638     if ((Lmediatest & Lmedialu) == Lmediatest) {
639       *Lcont  = 0;
640       Lstatusmedia = FALSE;
641       break;
642     }
643   }
644   set_waitwindow_title(Lstatusmedia, *Lmediatitle, Lmedialu, Lg);
645   gdk_flush ();
646 
647 
648   return TRUE;
649 }
650 
651 /* attente que l'utilisateur ai bien insere un cd */
waiting_for_user(gint Atitle,Tgrave * Ag,GSList * Arequiscd1,gint * Adetectcd1,Tdriveinfo * Ldriveident1)652 gboolean waiting_for_user(gint Atitle, Tgrave *Ag, GSList *Arequiscd1, gint *Adetectcd1, Tdriveinfo *Ldriveident1)
653 {
654   Tgrave *Lwaitg = sc_grave_load("window_waiting_cd.glade");
655   GtkWidget *Lparent = sc_grave_get_widget(Ag, "topwindow");
656   GtkWidget *Lwindow;
657   gchar *Ldevicetitle1 = NULL;
658   gchar *Ldevicetitle2 = NULL;
659   gint Lcont = 2;
660   gint Lpid = 0;
661   gboolean Labort = FALSE;
662   gboolean Linit = TRUE;
663   guint Ltimeout = 0;
664 
665   if (Atitle == _MEDIA_NONE) return TRUE;
666 
667   g_assert(Lwaitg);
668 
669   gtk_image_set_from_pixbuf(GTK_IMAGE(sc_grave_get_widget(Lwaitg, "imgwaiting")), get_image("CDRWIcon"));
670   Lwindow = GTK_WIDGET(sc_grave_get_widget(Lwaitg, "window_waiting_cd"));
671   g_signal_connect(G_OBJECT(sc_grave_get_widget(Lwaitg, "cancelbutton")), "clicked", G_CALLBACK(abort_encours), Lwaitg);
672 
673   sc_grave_set_data(Lwaitg, Lwindow, "window");
674   sc_grave_set_data(Lwaitg, &Lcont, "cont");
675   sc_grave_set_data(Lwaitg, &Labort, "gabort");
676   sc_grave_set_data(Lwaitg, &Lpid, "pid");
677 
678   if (Ldriveident1) {
679     sc_grave_set_data(Lwaitg, Ldriveident1, "device1");
680     sc_grave_set_data(Lwaitg, Adetectcd1, "detect1");
681     sc_grave_set_data(Lwaitg, &Atitle, "mediatitle1");
682     sc_grave_set_data(Lwaitg, Arequiscd1, "devicerequis1");
683 
684     set_waitwindow_title(TRUE, Atitle, -1, Lwaitg);
685   }
686 
687   gtk_window_set_transient_for(GTK_WINDOW(Lwindow), GTK_WINDOW(Lparent));
688   gtk_window_set_position(GTK_WINDOW(Lwindow), GTK_WIN_POS_CENTER_ALWAYS);
689 
690 
691   /* on appele une fois le callback pour verifier que l'utilisateur n'ai pas
692    * deja inser� le bon cd qui va bien */
693   sc_grave_set_data(Lwaitg, &Linit, "initdisp");
694   callback_waiting_for_user(Lwaitg);
695   Linit = FALSE;
696 
697   if (Lcont == 2 && Labort == FALSE) {
698     /* apparement non, on affiche la fenetre d'attente */
699     Ltimeout = g_timeout_add(1500, callback_waiting_for_user, Lwaitg);
700     do {
701       gtk_main_iteration();
702     } while (Lcont == 2 && Labort == FALSE);
703   }
704   sc_grave_del_data(Lwaitg, "initdisp");
705 
706   /* fin du timeout */
707   if (Ltimeout) g_source_remove(Ltimeout);
708 
709   gtk_widget_destroy(Lwindow);
710 
711 /*  g_free(Lident1); g_free(Lident2);*/
712   g_free(Ldevicetitle1); g_free(Ldevicetitle2);
713 
714   sc_grave_destroy(Lwaitg);
715 
716   return (Lcont == 0 && Labort == FALSE);
717 }
718 
matos_get_drive_info(Tgrave * Ag,gchar * Aname)719 Tdriveinfo *matos_get_drive_info(Tgrave *Ag, gchar *Aname)
720 {
721   return get_combo_value(sc_grave_get_widget(Ag, Aname));
722 }
723 
matos_get_device(Tdriveinfo * Adrive)724 gchar *matos_get_device(Tdriveinfo *Adrive)
725 {
726   GSList *Lcur;
727   gchar *Lcurbus;
728   gint i = 0;
729 
730   for (Lcur = Adrive->bus; Lcur; Lcur = g_slist_next(Lcur), i++) {
731     Lcurbus = (gchar *) Lcur->data;
732 
733     if (!strcmp(Lcurbus, "IDE") || !strncmp(Lcurbus, IDENT_SCSI, strlen(IDENT_SCSI)) || !strcmp(Lcurbus, "MANU")) {
734       return g_slist_nth_data(Adrive->dev, i);
735     }
736   }
737 
738   return NULL;
739 }
740 
matos_is_an_iso(Tgrave * Ag,gchar * Aname)741 gboolean matos_is_an_iso(Tgrave *Ag, gchar *Aname)
742 {
743   Tdriveinfo *Ldrive = get_combo_value(sc_grave_get_widget(Ag, Aname));
744 
745   return Ldrive ? TRUE : FALSE;
746 }
747 
748 /* creation ou ajout de la liste des medias requis */
manage_mediarequis(GSList * Acurlist,...)749 GSList *manage_mediarequis(GSList *Acurlist, ...)
750 {
751   GSList *Lcurlist = Acurlist ? Acurlist : NULL;
752   va_list Llist;
753   gint Lt;
754 
755   va_start(Llist, Acurlist);
756   while (1) {
757     Lt = va_arg(Llist, gint);
758     if (Lt == -1) break;
759 
760   Lcurlist = g_slist_append(Lcurlist, GINT_TO_POINTER(Lt));
761   }
762   va_end(Llist);
763 
764   return Lcurlist;
765 }
766 
767 /* try to umount device when it's mounted
768  * scan /etc/ftab file to do this */
matos_umount_device(Tdriveinfo * Adrive,GError ** Aerror)769 gboolean matos_umount_device(Tdriveinfo *Adrive, GError **Aerror)
770 {
771   gchar *Lcontent = NULL;
772   gint i;
773   gchar **Larrbuf, *Lcur, *s, *Lcurdev = NULL;
774   gchar Lcommand[_BUF_SIZE];
775   GSList *Llistdev;
776   gboolean Lfind = FALSE, Lstatus = FALSE;
777 
778   if (!g_file_get_contents("/etc/mtab", &Lcontent, NULL, Aerror) || !Lcontent) return FALSE;
779   Larrbuf = g_strsplit(Lcontent, "\n", 0);
780 
781   for (i=0; Larrbuf[i] && !Lfind; i++) {
782     s = Lcur = Larrbuf[i];
783     if (!*Lcur) continue;
784 
785   _DEB("deb => [%s]", Lcur);
786 
787     while (g_ascii_isalnum(*s) || *s=='/') s++;
788     *s=0;
789     if ((s=strchr(Lcur, '='))) Lcur=s+1;
790 
791     for (Llistdev = Adrive->dev; Llistdev; Llistdev = g_slist_next(Llistdev)) {
792       Lcurdev = (gchar *) Llistdev->data;
793 _DEB("comp de [%s] et [%s]", Lcurdev,Lcur);
794       if (!strcmp(Lcurdev, Lcur)) {
795         Lfind = TRUE;
796         break;
797       }
798     }
799   }
800 
801   if (Lfind && Lcurdev) {
802     g_snprintf(Lcommand, sizeof(Lcommand)-1, "/bin/umount %s", Lcurdev);
803 
804     _DEB("try to umount [%s]", Lcommand);
805 
806     Lstatus = g_spawn_command_line_async(Lcommand, Aerror);
807   }
808 
809   g_strfreev(Larrbuf);
810   g_free(Lcontent);
811 
812   return Lstatus;
813 }
814 
matos_maj_drive_info(Tdriveinfo * Adrive,gchar * Adev,GError ** Aerror)815 gboolean matos_maj_drive_info(Tdriveinfo *Adrive, gchar *Adev, GError **Aerror)
816 {
817   Adrive->type = 0;
818 
819   cdrecord_maj_drive_info(Adrive, Adev, Aerror);
820 
821   /* use /proc/sys/dev/cdrom/info with linux to detect DVD capability */
822   proc_maj_drive_info(Adrive, Aerror);
823 
824   return TRUE;
825 }
826 
827 /*
828  * vim:et:ts=8:sts=2:sw=2
829  */
830