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