let you install theme archives
[dana/obconf.git] / src / install.c
1 #include "install.h"
2 #include "main.h"
3 #include "gettext.h"
4
5 #include <errno.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <zlib.h>
10 #include <libtar.h>
11
12 static gzFile gzf = NULL;
13
14 static int gzopen_frontend(const char *path, int oflags, int mode)
15 {
16     int fd;
17
18     if ((fd = open(path, oflags, mode)) < 0) return -1;
19     if (!(gzf = gzdopen(fd, "rb"))) return -1;
20     return 1;
21 }
22
23 static int gzclose_frontend(int nothing)
24 {
25     g_return_val_if_fail(gzf != NULL, 0);
26     return gzclose(gzf);
27 }
28
29 static ssize_t gzread_frontend(int nothing, void *buf, size_t s)
30 {
31     return gzread(gzf, buf, s);
32 }
33
34 static ssize_t gzwrite_frontend(int nothing, const void *buf, size_t s)
35 {
36     return gzwrite(gzf, buf, s);
37 }
38
39 tartype_t funcs = {
40     (openfunc_t) gzopen_frontend,
41     (closefunc_t) gzclose_frontend,
42     (readfunc_t) gzread_frontend,
43     (writefunc_t) gzwrite_frontend
44 };
45
46 gboolean install_theme(char *path, char *theme)
47 {
48     TAR *t;
49     gchar *dest;
50     gint r;
51     gchar *glob;
52     GtkWidget *w;
53
54     dest = g_build_path(G_DIR_SEPARATOR_S, g_get_home_dir(), ".themes", NULL);
55     r = mkdir(dest, 0777);
56     if (r == -1 && errno != EEXIST) {
57         w = gtk_message_dialog_new(GTK_WINDOW(mainwin),
58                                    GTK_DIALOG_DESTROY_WITH_PARENT |
59                                    GTK_DIALOG_MODAL,
60                                    GTK_MESSAGE_ERROR,
61                                    GTK_BUTTONS_OK,
62                                    _("Unable to create directory \"%s\": %s"),
63                                    dest, strerror(errno));
64         gtk_dialog_run(GTK_DIALOG(w));
65         gtk_widget_destroy(w);
66         return FALSE;
67     }
68     if (chdir(dest) == -1) {
69         w = gtk_message_dialog_new(GTK_WINDOW(mainwin),
70                                    GTK_DIALOG_DESTROY_WITH_PARENT |
71                                    GTK_DIALOG_MODAL,
72                                    GTK_MESSAGE_ERROR,
73                                    GTK_BUTTONS_OK,
74                                    _("Unable to move to directory \"%s\": %s"),
75                                    dest, strerror(errno));
76         gtk_dialog_run(GTK_DIALOG(w));
77         gtk_widget_destroy(w);
78         return FALSE;
79     }
80
81     if (tar_open(&t, path, &funcs, 0, O_RDONLY, TAR_GNU) == -1) {
82         w = gtk_message_dialog_new(GTK_WINDOW(mainwin),
83                                    GTK_DIALOG_DESTROY_WITH_PARENT |
84                                    GTK_DIALOG_MODAL,
85                                    GTK_MESSAGE_ERROR,
86                                    GTK_BUTTONS_OK,
87                                    _("Unable to open the file \"%s\": %s"),
88                                    path, strerror(errno));
89         gtk_dialog_run(GTK_DIALOG(w));
90         gtk_widget_destroy(w);
91         return FALSE;
92     }
93
94     glob = g_strdup_printf("%s/openbox-3/*", theme);
95     r = tar_extract_glob(t, glob, dest);
96     g_free(glob);
97     tar_close(t);
98
99     if (r != 0) {
100         w = gtk_message_dialog_new(GTK_WINDOW(mainwin),
101                                    GTK_DIALOG_DESTROY_WITH_PARENT |
102                                    GTK_DIALOG_MODAL,
103                                    GTK_MESSAGE_ERROR,
104                                    GTK_BUTTONS_OK,
105                                    _("Unable to extract the file \"%s\".\nIt does not appear to be a valid Openbox theme archive (in tar.gz format)."),
106                                    path, strerror(errno));
107         gtk_dialog_run(GTK_DIALOG(w));
108         gtk_widget_destroy(w);
109
110         g_free(dest);
111         return FALSE;
112     }
113
114     w = gtk_message_dialog_new(GTK_WINDOW(mainwin),
115                                GTK_DIALOG_DESTROY_WITH_PARENT |
116                                GTK_DIALOG_MODAL,
117                                GTK_MESSAGE_INFO,
118                                GTK_BUTTONS_OK,
119                                _("%s was installed to %s"),
120                                theme, dest);
121     gtk_dialog_run(GTK_DIALOG(w));
122     gtk_widget_destroy(w);
123
124     g_free(dest);
125
126     return TRUE;
127 }