2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#define __USE_XOPEN_EXTENDED
27
#include <glib/gstdio.h>
28
#include <glib/gi18n.h>
29
#include <curl/curl.h>
31
#include "../config.h"
32
#include "cairo-dock-keyfile-utilities.h"
33
//#include "cairo-dock-dock-manager.h"
34
//#include "cairo-dock-gui-manager.h"
35
#include "cairo-dock-task.h"
36
#include "cairo-dock-log.h"
37
#include "cairo-dock-internal-system.h"
38
#include "cairo-dock-packages.h"
40
#define CAIRO_DOCK_DEFAULT_PACKAGES_LIST_FILE "list.conf"
42
static gchar *s_cPackageServerAdress = NULL;
48
gchar *cairo_dock_uncompress_file (const gchar *cArchivePath, const gchar *cExtractTo, const gchar *cRealArchiveName)
50
//\_______________ on cree le repertoire d'extraction.
51
if (!g_file_test (cExtractTo, G_FILE_TEST_EXISTS))
53
if (g_mkdir (cExtractTo, 7*8*8+7*8+5) != 0)
55
cd_warning ("couldn't create directory %s", cExtractTo);
60
//\_______________ on construit le chemin local du dossier apres son extraction.
61
gchar *cLocalFileName;
62
if (cRealArchiveName == NULL)
63
cRealArchiveName = cArchivePath;
64
gchar *str = strrchr (cRealArchiveName, '/');
66
cLocalFileName = g_strdup (str+1);
68
cLocalFileName = g_strdup (cRealArchiveName);
70
if (g_str_has_suffix (cLocalFileName, ".tar.gz"))
71
cLocalFileName[strlen(cLocalFileName)-7] = '\0';
72
else if (g_str_has_suffix (cLocalFileName, ".tar.bz2"))
73
cLocalFileName[strlen(cLocalFileName)-8] = '\0';
74
else if (g_str_has_suffix (cLocalFileName, ".tgz"))
75
cLocalFileName[strlen(cLocalFileName)-4] = '\0';
76
g_return_val_if_fail (cLocalFileName != NULL && *cLocalFileName != '\0', NULL);
78
gchar *cResultPath = g_strdup_printf ("%s/%s", cExtractTo, cLocalFileName);
79
g_free (cLocalFileName);
81
//\_______________ on efface un dossier identique prealable.
82
if (g_file_test (cResultPath, G_FILE_TEST_EXISTS))
84
gchar *cCommand = g_strdup_printf ("rm -rf \"%s\"", cResultPath);
85
int r = system (cCommand);
89
//\_______________ on decompresse l'archive.
90
gchar *cCommand = g_strdup_printf ("tar xf%c \"%s\" -C \"%s\"", (g_str_has_suffix (cArchivePath, "bz2") ? 'j' : 'z'), cArchivePath, cExtractTo);
91
cd_debug ("tar : %s\n", cCommand);
92
int r = system (cCommand);
95
cd_warning ("an error occured while executing '%s'", cCommand);
103
static inline CURL *_init_curl_connection (const gchar *cURL)
105
CURL *handle = curl_easy_init ();
106
curl_easy_setopt (handle, CURLOPT_URL, cURL);
107
if (mySystem.cConnectionProxy != NULL)
109
curl_easy_setopt (handle, CURLOPT_PROXY, mySystem.cConnectionProxy);
110
if (mySystem.iConnectionPort != 0)
111
curl_easy_setopt (handle, CURLOPT_PROXYPORT, mySystem.iConnectionPort);
112
if (mySystem.cConnectionUser != NULL && mySystem.
113
cConnectionPasswd != NULL)
115
gchar *cUserPwd = g_strdup_printf ("%s:%s", mySystem.cConnectionUser, mySystem.
117
curl_easy_setopt (handle, CURLOPT_PROXYUSERPWD, cUserPwd);
119
/*curl_easy_setopt (handle, CURLOPT_PROXYUSERNAME, mySystem.cConnectionUser);
120
if (mySystem.cConnectionPasswd != NULL)
121
curl_easy_setopt (handle, CURLOPT_PROXYPASSWORD, mySystem.cConnectionPasswd);*/ // a partir de libcurl 7.19.1, donc apres Jaunty
124
curl_easy_setopt (handle, CURLOPT_TIMEOUT, mySystem.iConnectionMaxTime);
125
curl_easy_setopt (handle, CURLOPT_CONNECTTIMEOUT, mySystem.iConnectionTimeout);
126
curl_easy_setopt (handle, CURLOPT_NOSIGNAL, 1); // With CURLOPT_NOSIGNAL set non-zero, curl will not use any signals; sinon curl se vautre apres le timeout, meme si le download s'est bien passe !
130
static size_t _write_data_to_file (gpointer buffer, size_t size, size_t nmemb, FILE *fd)
132
return fwrite (buffer, size, nmemb, fd);
134
gchar *cairo_dock_download_file (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, const gchar *cExtractTo, GError **erreur)
136
//g_print ("%s (%s, %s, %s, %s)\n", __func__, cServerAdress, cDistantFilePath, cDistantFileName, cExtractTo);
137
//\_______________ On reserve un fichier temporaire.
138
gchar *cTmpFilePath = g_strdup ("/tmp/cairo-dock-net-file.XXXXXX");
139
int fds = mkstemp (cTmpFilePath);
142
g_set_error (erreur, 1, 1, "couldn't create temporary file '%s'", cTmpFilePath);
143
g_free (cTmpFilePath);
147
//\_______________ On lance le download.
148
gchar *cURL = (cServerAdress ? g_strdup_printf ("%s/%s/%s", cServerAdress, cDistantFilePath, cDistantFileName) : g_strdup (cDistantFileName));
149
cd_debug ("cURL : %s\n", cURL);
150
FILE *f = fopen (cTmpFilePath, "wb");
151
g_return_val_if_fail (f, NULL);
153
CURL *handle = _init_curl_connection (cURL);
154
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, _write_data_to_file);
155
curl_easy_setopt(handle, CURLOPT_WRITEDATA, f);
157
CURLcode r = curl_easy_perform (handle);
161
cd_warning ("an error occured while downloading '%s'", cURL);
162
g_remove (cTmpFilePath);
163
g_free (cTmpFilePath);
167
curl_easy_cleanup (handle);
171
//\_______________ On teste que le fichier est non vide.
172
gboolean bOk = (cTmpFilePath != NULL);
176
stat (cTmpFilePath, &buf);
177
bOk = (buf.st_size > 0);
181
g_set_error (erreur, 1, 1, "couldn't get distant file %s", cDistantFileName);
182
g_remove (cTmpFilePath);
183
g_free (cTmpFilePath);
188
//\_______________ On l'extrait si c'est une archive.
189
if (cTmpFilePath != NULL && cExtractTo != NULL)
191
cd_debug ("uncompressing ...\n");
192
gchar *cPath = cairo_dock_uncompress_file (cTmpFilePath, cExtractTo, cDistantFileName);
193
g_remove (cTmpFilePath);
194
g_free (cTmpFilePath);
195
cTmpFilePath = cPath;
201
static void _dl_file (gpointer *pSharedMemory)
203
GError *erreur = NULL;
204
pSharedMemory[6] = cairo_dock_download_file (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2], pSharedMemory[3], &erreur);
207
cd_warning (erreur->message);
208
g_error_free (erreur);
211
static gboolean _finish_dl (gpointer *pSharedMemory)
213
if (pSharedMemory[6] == NULL)
214
cd_warning ("couldn't get distant file %s", pSharedMemory[2]);
216
GFunc pCallback = pSharedMemory[4];
217
pCallback (pSharedMemory[6], pSharedMemory[5]);
220
static void _free_dl (gpointer *pSharedMemory)
222
g_free (pSharedMemory[0]);
223
g_free (pSharedMemory[1]);
224
g_free (pSharedMemory[2]);
225
g_free (pSharedMemory[3]);
226
g_free (pSharedMemory[6]);
227
g_free (pSharedMemory);
229
CairoDockTask *cairo_dock_download_file_async (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, const gchar *cExtractTo, GFunc pCallback, gpointer data)
231
gpointer *pSharedMemory = g_new0 (gpointer, 7);
232
pSharedMemory[0] = g_strdup (cServerAdress);
233
pSharedMemory[1] = g_strdup (cDistantFilePath);
234
pSharedMemory[2] = g_strdup (cDistantFileName);
235
pSharedMemory[3] = g_strdup (cExtractTo);
236
pSharedMemory[4] = pCallback;
237
pSharedMemory[5] = data;
238
CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _dl_file, (CairoDockUpdateSyncFunc) _finish_dl, (GFreeFunc) _free_dl, pSharedMemory);
239
cairo_dock_launch_task (pTask);
244
gchar *cairo_dock_get_distant_file_content (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, GError **erreur)
246
gchar *cURL = g_strdup_printf ("%s/%s/%s", cServerAdress, cDistantFilePath, cDistantFileName);
247
gchar *cContent = cairo_dock_get_url_data (cURL, erreur);
252
static size_t _write_data_to_buffer (gpointer buffer, size_t size, size_t nmemb, GList **list_ptr)
254
GList *pList = *list_ptr;
255
*list_ptr = g_list_prepend (*list_ptr, g_strndup (buffer, size * nmemb));
258
gchar *cairo_dock_get_url_data (const gchar *cURL, GError **erreur)
260
//\_______________ On lance le download.
261
cd_debug ("getting data from '%s' ...", cURL);
262
CURL *handle = _init_curl_connection (cURL);
263
curl_easy_setopt (handle, CURLOPT_WRITEFUNCTION, (curl_write_callback)_write_data_to_buffer);
264
gpointer *pointer_to_list = g_new0 (gpointer, 1);
265
curl_easy_setopt (handle, CURLOPT_WRITEDATA, pointer_to_list);
267
CURLcode r = curl_easy_perform (handle);
271
cd_warning ("an error occured while downloading '%s' : %s", cURL, curl_easy_strerror (r));
272
g_free (pointer_to_list);
273
pointer_to_list = NULL;
276
curl_easy_cleanup (handle);
278
//\_______________ On recupere les donnees.
279
gchar *cContent = NULL;
280
if (pointer_to_list != NULL)
282
GList *l, *pList = *pointer_to_list;
284
for (l = pList; l != NULL; l = l->next)
287
n += strlen (l->data);
292
cContent = g_new0 (char, n+1);
293
char *ptr = cContent;
294
for (l = g_list_last (pList); l != NULL; l = l->prev)
298
n = strlen (l->data);
299
memcpy (ptr, l->data, n);
306
g_free (pointer_to_list);
312
static void _dl_file_content (gpointer *pSharedMemory)
314
GError *erreur = NULL;
315
pSharedMemory[5] = cairo_dock_get_distant_file_content (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2], &erreur);
318
cd_warning (erreur->message);
319
g_error_free (erreur);
322
static gboolean _finish_dl_content (gpointer *pSharedMemory)
324
if (pSharedMemory[5] == NULL)
325
cd_warning ("couldn't get distant file %s", pSharedMemory[2]);
327
GFunc pCallback = pSharedMemory[3];
328
pCallback (pSharedMemory[5], pSharedMemory[4]);
331
static void _free_dl_content (gpointer *pSharedMemory)
333
g_free (pSharedMemory[0]);
334
g_free (pSharedMemory[1]);
335
g_free (pSharedMemory[2]);
336
g_free (pSharedMemory[5]);
337
g_free (pSharedMemory);
339
CairoDockTask *cairo_dock_get_distant_file_content_async (const gchar *cServerAdress, const gchar *cDistantFilePath, const gchar *cDistantFileName, GFunc pCallback, gpointer data)
341
gpointer *pSharedMemory = g_new0 (gpointer, 6);
342
pSharedMemory[0] = g_strdup (cServerAdress);
343
pSharedMemory[1] = g_strdup (cDistantFilePath);
344
pSharedMemory[2] = g_strdup (cDistantFileName);
345
pSharedMemory[3] = pCallback;
346
pSharedMemory[4] = data;
347
CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _dl_file_content, (CairoDockUpdateSyncFunc) _finish_dl_content, (GFreeFunc) _free_dl_content, pSharedMemory);
348
cairo_dock_launch_task (pTask);
356
void cairo_dock_free_package (CairoDockPackage *pPackage)
358
if (pPackage == NULL)
360
g_free (pPackage->cPackagePath);
361
g_free (pPackage->cAuthor);
362
g_free (pPackage->cDisplayedName);
366
static inline int _get_rating (const gchar *cPackagesDir, const gchar *cPackageName)
368
gchar *cRatingFile = g_strdup_printf ("%s/.rating/%s", cPackagesDir, cPackageName);
371
gchar *cContent = NULL;
372
g_file_get_contents (cRatingFile,
378
iRating = atoi (cContent);
381
g_free (cRatingFile);
384
GHashTable *cairo_dock_list_local_packages (const gchar *cPackagesDir, GHashTable *hProvidedTable, gboolean bUpdatePackageValidity, GError **erreur)
386
cd_debug ("%s (%s)", __func__, cPackagesDir);
387
GError *tmp_erreur = NULL;
388
GDir *dir = g_dir_open (cPackagesDir, 0, &tmp_erreur);
389
if (tmp_erreur != NULL)
391
g_propagate_error (erreur, tmp_erreur);
392
return hProvidedTable;
395
GHashTable *pPackageTable = (hProvidedTable != NULL ? hProvidedTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_package));
397
CairoDockPackageType iType = (strncmp (cPackagesDir, "/usr", 4) == 0 ?
398
CAIRO_DOCK_LOCAL_PACKAGE :
399
CAIRO_DOCK_USER_PACKAGE);
400
GString *sRatingFile = g_string_new (cPackagesDir);
402
CairoDockPackage *pPackage;
403
const gchar *cPackageName;
404
while ((cPackageName = g_dir_read_name (dir)) != NULL)
406
// on ecarte les fichiers caches.
407
if (*cPackageName == '.')
410
// on ecarte les non repertoires.
411
cPackagePath = g_strdup_printf ("%s/%s", cPackagesDir, cPackageName);
412
if (! g_file_test (cPackagePath, G_FILE_TEST_IS_DIR))
414
g_free (cPackagePath);
418
// on insere le package dans la table.
419
pPackage = g_new0 (CairoDockPackage, 1);
420
pPackage->cPackagePath = cPackagePath;
421
pPackage->cDisplayedName = g_strdup (cPackageName);
422
pPackage->iType = iType;
423
pPackage->iRating = _get_rating (cPackagesDir, cPackageName);
424
g_hash_table_insert (pPackageTable, g_strdup (cPackageName), pPackage); // donc ecrase un package installe ayant le meme nom.
427
return pPackageTable;
430
static inline int _convert_date (int iDate)
434
m = (iDate - y*10000) / 100;
436
return (d + m*30 + y*365);
438
static void _cairo_dock_parse_package_list (GKeyFile *pKeyFile, const gchar *cServerAdress, const gchar *cDirectory, GHashTable *pPackageTable)
441
time_t epoch = (time_t) time (NULL);
442
struct tm currentTime;
443
localtime_r (&epoch, ¤tTime);
444
int day = currentTime.tm_mday; // dans l'intervalle 1 a 31.
445
int month = currentTime.tm_mon + 1; // dans l'intervalle 0 a 11.
446
int year = 1900 + currentTime.tm_year; // tm_year = nombre d'annees Ć©coulees depuis 1900.
447
int now = day + month * 30 + year * 365;
449
// liste des packages.
451
gchar **pGroupList = g_key_file_get_groups (pKeyFile, &length);
452
g_return_if_fail (pGroupList != NULL); // rien a charger dans la table, on quitte.
454
// on parcourt la liste.
455
gchar *cPackageName, *cDate, *cDisplayedName, *cName, *cAuthor;
456
CairoDockPackage *pPackage;
457
CairoDockPackageType iType;
459
int iCreationDate, iLastModifDate, iLocalDate, iSobriety, iCategory;
460
int last_modif, creation_date;
462
for (i = 0; i < length; i ++)
464
cPackageName = pGroupList[i];
465
iCreationDate = g_key_file_get_integer (pKeyFile, cPackageName, "creation", NULL);
466
iLastModifDate = g_key_file_get_integer (pKeyFile, cPackageName, "last modif", NULL);
467
iSobriety = g_key_file_get_integer (pKeyFile, cPackageName, "sobriety", NULL);
468
iCategory = g_key_file_get_integer (pKeyFile, cPackageName, "category", NULL);
469
fSize = g_key_file_get_double (pKeyFile, cPackageName, "size", NULL);
470
cAuthor = g_key_file_get_string (pKeyFile, cPackageName, "author", NULL);
471
if (cAuthor && *cAuthor == '\0')
477
if (g_key_file_has_key (pKeyFile, cPackageName, "name", NULL))
479
cName = g_key_file_get_string (pKeyFile, cPackageName, "name", NULL);
482
// creation < 30j && pas sur le disque -> new
483
// sinon last modif < 30j && last use < last modif -> updated
486
// on surcharge les packages locaux en cas de nouvelle version.
487
CairoDockPackage *pSamePackage = g_hash_table_lookup (pPackageTable, cPackageName);
488
if (pSamePackage != NULL) // le package existe en local.
490
// on regarde de quand date cette version locale.
491
gchar *cVersionFile = g_strdup_printf ("%s/last-modif", pSamePackage->cPackagePath);
493
gchar *cContent = NULL;
494
g_file_get_contents (cVersionFile,
498
if (cContent == NULL) // le package n'a pas encore de fichier de date
500
// on ne peut pas savoir quand l'utilisateur a mis a jour le package pour la derniere fois;
501
// on va supposer que l'on ne met pas a jour ses packages tres regulierement, donc il est probable qu'il l'ait fait il y'a au moins 1 mois.
502
// de cette facon, les packages mis a jour recemment (il y'a moins d'1 mois) apparaitront "updated".
504
iLocalDate = day + (month - 1) * 1e2 + year * 1e4;
506
iLocalDate = day + 12 * 1e2 + (year - 1) * 1e4;
507
cDate = g_strdup_printf ("%d", iLocalDate);
508
g_file_set_contents (cVersionFile,
515
iLocalDate = atoi (cContent);
517
g_free (cVersionFile);
520
if (iLocalDate < iLastModifDate) // la copie locale est plus ancienne.
522
iType = CAIRO_DOCK_UPDATED_PACKAGE;
524
else // c'est deja la derniere version disponible, on en reste la.
526
pSamePackage->iSobriety = iSobriety; // par contre on en profite pour renseigner la sobriete.
527
g_free (pSamePackage->cDisplayedName);
528
pSamePackage->cDisplayedName = g_strdup_printf ("%s by %s", cName ? cName : cPackageName, (cAuthor ? cAuthor : "---"));
529
pSamePackage->cAuthor = cAuthor;
531
g_free (cPackageName);
535
pPackage = pSamePackage;
536
g_free (pPackage->cPackagePath);
537
g_free (pPackage->cAuthor);
538
g_free (pPackage->cDisplayedName);
540
else // package encore jamais telecharge.
542
last_modif = _convert_date (iLastModifDate);
543
creation_date = _convert_date (iCreationDate);
545
if (now - creation_date < 30) // les packages restent nouveaux pendant 1 mois.
546
iType = CAIRO_DOCK_NEW_PACKAGE;
547
else if (now - last_modif < 30) // les packages restent mis a jour pendant 1 mois.
548
iType = CAIRO_DOCK_UPDATED_PACKAGE;
550
iType = CAIRO_DOCK_DISTANT_PACKAGE;
552
pPackage = g_new0 (CairoDockPackage, 1);
553
g_hash_table_insert (pPackageTable, cPackageName, pPackage);
554
pPackage->iRating = g_key_file_get_integer (pKeyFile, cPackageName, "rating", NULL); // par contre on affiche la note que l'utilisateur avait precedemment etablie.
557
pPackage->cPackagePath = g_strdup_printf ("%s/%s/%s", cServerAdress, cDirectory, cPackageName);
558
pPackage->iType = iType;
559
pPackage->fSize = fSize;
560
pPackage->cAuthor = cAuthor;
561
pPackage->cDisplayedName = g_strdup_printf ("%s by %s [%.2f MB]", cName ? cName : cPackageName, (cAuthor ? cAuthor : "---"), fSize);
562
pPackage->iSobriety = iSobriety;
563
pPackage->iCategory = iCategory;
564
pPackage->iCreationDate = iCreationDate;
565
pPackage->iLastModifDate = iLastModifDate;
567
g_free (pGroupList); // les noms des packages sont desormais dans la hash-table.
569
GHashTable *cairo_dock_list_net_packages (const gchar *cServerAdress, const gchar *cDirectory, const gchar *cListFileName, GHashTable *hProvidedTable, GError **erreur)
571
g_return_val_if_fail (cServerAdress != NULL && *cServerAdress != '\0', hProvidedTable);
572
cd_message ("listing net packages on %s/%s ...", cServerAdress, cDirectory);
574
// On recupere la liste des packages distants.
575
GError *tmp_erreur = NULL;
576
gchar *cContent = cairo_dock_get_distant_file_content (cServerAdress, cDirectory, cListFileName, &tmp_erreur);
577
if (tmp_erreur != NULL)
579
cd_warning ("couldn't retrieve packages on %s (check that your connection is alive, or retry later)", cServerAdress);
580
g_propagate_error (erreur, tmp_erreur);
581
return hProvidedTable;
584
// on verifie son integrite.
585
if (cContent == NULL || strncmp (cContent, "#!CD", 4) != 0) // avec une connexion wifi etablie sur un operateur auquel on ne s'est pas logue, il peut nous renvoyer des messages au lieu de juste rien. On filtre ca par un entete dedie.
587
cd_warning ("empty packages list on %s (check that your connection is alive, or retry later)", cServerAdress);
588
g_set_error (erreur, 1, 1, "empty packages list on %s", cServerAdress);
590
return hProvidedTable;
593
// on charge la liste dans un fichier de cles.
594
GKeyFile *pKeyFile = g_key_file_new ();
595
g_key_file_load_from_data (pKeyFile,
601
if (tmp_erreur != NULL)
603
cd_warning ("invalid list of packages (%s)\n(check that your connection is alive, or retry later)", cServerAdress);
604
g_propagate_error (erreur, tmp_erreur);
605
g_key_file_free (pKeyFile);
606
return hProvidedTable;
609
// on parse la liste dans une table de hashage.
610
GHashTable *pPackageTable = (hProvidedTable != NULL ? hProvidedTable : g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_package));
612
_cairo_dock_parse_package_list (pKeyFile, cServerAdress, cDirectory, pPackageTable);
614
g_key_file_free (pKeyFile);
616
return pPackageTable;
619
GHashTable *cairo_dock_list_packages (const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir)
621
cd_message ("%s (%s, %s, %s)", __func__, cSharePackagesDir, cUserPackagesDir, cDistantPackagesDir);
622
GError *erreur = NULL;
623
GHashTable *pPackageTable = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cairo_dock_free_package);
625
//\______________ On recupere les packages pre-installes.
626
if (cSharePackagesDir != NULL)
627
pPackageTable = cairo_dock_list_local_packages (cSharePackagesDir, pPackageTable, cDistantPackagesDir != NULL, &erreur);
630
cd_warning ("while listing pre-installed packages in '%s' : %s", cSharePackagesDir, erreur->message);
631
g_error_free (erreur);
635
//\______________ On recupere les packages utilisateurs (qui ecrasent donc les precedents).
636
if (cUserPackagesDir != NULL)
637
pPackageTable = cairo_dock_list_local_packages (cUserPackagesDir, pPackageTable, cDistantPackagesDir != NULL, &erreur);
640
cd_warning ("while listing user packages in '%s' : %s", cSharePackagesDir, erreur->message);
641
g_error_free (erreur);
645
//\______________ On recupere les packages distants (qui surchargent tous les packages).
646
if (cDistantPackagesDir != NULL && s_cPackageServerAdress)
648
pPackageTable = cairo_dock_list_net_packages (s_cPackageServerAdress, cDistantPackagesDir, CAIRO_DOCK_DEFAULT_PACKAGES_LIST_FILE, pPackageTable, &erreur);
651
cd_warning ("while listing distant packages in '%s/%s' : %s", s_cPackageServerAdress, cDistantPackagesDir, erreur->message);
652
g_error_free (erreur);
657
return pPackageTable;
660
static void _list_packages (gpointer *pSharedMemory)
662
pSharedMemory[5] = cairo_dock_list_packages (pSharedMemory[0], pSharedMemory[1], pSharedMemory[2]);
664
static gboolean _finish_list_packages (gpointer *pSharedMemory)
666
if (pSharedMemory[5] == NULL)
667
cd_warning ("couldn't get distant packages in '%s'", pSharedMemory[2]);
669
GFunc pCallback = pSharedMemory[3];
670
pCallback (pSharedMemory[5], pSharedMemory[4]);
673
static void _discard_list_packages (gpointer *pSharedMemory)
675
g_free (pSharedMemory[0]);
676
g_free (pSharedMemory[1]);
677
g_free (pSharedMemory[2]);
678
if (pSharedMemory[5] != NULL)
679
g_hash_table_unref (pSharedMemory[5]);
680
g_free (pSharedMemory);
682
CairoDockTask *cairo_dock_list_packages_async (const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, CairoDockGetPackagesFunc pCallback, gpointer data)
684
gpointer *pSharedMemory = g_new0 (gpointer, 6);
685
pSharedMemory[0] = g_strdup (cSharePackagesDir);
686
pSharedMemory[1] = g_strdup (cUserPackagesDir);
687
pSharedMemory[2] = g_strdup (cDistantPackagesDir);
688
pSharedMemory[3] = pCallback;
689
pSharedMemory[4] = data;
690
CairoDockTask *pTask = cairo_dock_new_task_full (0, (CairoDockGetDataAsyncFunc) _list_packages, (CairoDockUpdateSyncFunc) _finish_list_packages, (GFreeFunc) _discard_list_packages, pSharedMemory);
691
cairo_dock_launch_task (pTask);
695
gchar *cairo_dock_get_package_path (const gchar *cPackageName, const gchar *cSharePackagesDir, const gchar *cUserPackagesDir, const gchar *cDistantPackagesDir, CairoDockPackageType iGivenType)
697
cd_message ("%s (%s, %s, %s)", __func__, cSharePackagesDir, cUserPackagesDir, cDistantPackagesDir);
698
if (cPackageName == NULL || *cPackageName == '\0')
700
CairoDockPackageType iType = cairo_dock_extract_package_type_from_name (cPackageName); // juste au cas ou, mais normalement c'est plutot a l'appelant d'extraire le type de theme.
701
if (iType == CAIRO_DOCK_ANY_PACKAGE)
703
gchar *cPackagePath = NULL;
705
//g_print ("iType : %d\n", iType);
706
if (cUserPackagesDir != NULL && /*iType != CAIRO_DOCK_DISTANT_PACKAGE && iType != CAIRO_DOCK_NEW_PACKAGE && */iType != CAIRO_DOCK_UPDATED_PACKAGE)
708
cPackagePath = g_strdup_printf ("%s/%s", cUserPackagesDir, cPackageName);
710
if (g_file_test (cPackagePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
715
g_free (cPackagePath);
719
if (cSharePackagesDir != NULL && iType != CAIRO_DOCK_UPDATED_PACKAGE)
721
cPackagePath = g_strdup_printf ("%s/%s", cSharePackagesDir, cPackageName);
722
if (g_file_test (cPackagePath, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))
724
g_free (cPackagePath);
728
if (cDistantPackagesDir != NULL && s_cPackageServerAdress)
730
gchar *cDistantFileName = g_strdup_printf ("%s/%s.tar.gz", cPackageName, cPackageName);
731
GError *erreur = NULL;
732
cPackagePath = cairo_dock_download_file (s_cPackageServerAdress, cDistantPackagesDir, cDistantFileName, cUserPackagesDir, &erreur);
733
g_free (cDistantFileName);
736
cd_warning ("couldn't retrieve distant package %s : %s" , cPackageName, erreur->message);
737
g_error_free (erreur);
739
else // on se souvient de la date a laquelle on a mis a jour le package pour la derniere fois.
741
gchar *cVersionFile = g_strdup_printf ("%s/last-modif", cPackagePath);
742
time_t epoch = (time_t) time (NULL);
743
struct tm currentTime;
744
localtime_r (&epoch, ¤tTime);
745
int now = (currentTime.tm_mday+1) + (currentTime.tm_mon+1) * 1e2 + (1900+currentTime.tm_year) * 1e4;
746
gchar *cDate = g_strdup_printf ("%d", now);
747
g_file_set_contents (cVersionFile,
752
g_free (cVersionFile);
756
cd_debug (" ====> cPackagePath : %s", cPackagePath);
761
CairoDockPackageType cairo_dock_extract_package_type_from_name (const gchar *cPackageName)
763
if (cPackageName == NULL)
764
return CAIRO_DOCK_ANY_PACKAGE;
765
CairoDockPackageType iType = CAIRO_DOCK_ANY_PACKAGE;
766
int l = strlen (cPackageName);
767
if (cPackageName[l-1] == ']')
769
gchar *str = strrchr (cPackageName, '[');
770
if (str != NULL && g_ascii_isdigit (*(str+1)))
772
iType = atoi (str+1);
779
#define _check_dir(cDirPath) \
780
if (! g_file_test (cDirPath, G_FILE_TEST_IS_DIR)) {\
781
if (g_mkdir (cDirPath, 7*8*8+7*8+7) != 0) {\
782
cd_warning ("couldn't create directory %s", cDirPath);\
786
void cairo_dock_init_package_manager (gchar *cPackageServerAdress)
788
s_cPackageServerAdress = cPackageServerAdress;
790
//\___________________ On initialise le gestionnaire de download.
791
curl_global_init (CURL_GLOBAL_DEFAULT);