]> www.fi.muni.cz Git - evince.git/blob - libdocument/ev-file-helpers.c
Add --without-libgnome, check for libgnome and libgnomeui separately, and
[evince.git] / libdocument / ev-file-helpers.c
1 /*
2  *  Copyright (C) 2002 Jorn Baayen
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2, or (at your option)
7  *  any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  *  $Id$
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <glib.h>
30 #include <glib/gstdio.h>
31 #include <errno.h>
32 #include <libgnomevfs/gnome-vfs-uri.h>
33 #include <libgnomevfs/gnome-vfs-utils.h>
34 #include <libgnomevfs/gnome-vfs-ops.h>
35 #include <libgnomevfs/gnome-vfs-xfer.h>
36
37 #if WITH_GNOME
38 #include <libgnome/gnome-init.h>
39 #endif
40
41 #include "ev-file-helpers.h"
42
43 static gchar *dot_dir = NULL;
44 static gchar *tmp_dir = NULL;
45 static gint   count = 0;
46
47 static gboolean
48 ensure_dir_exists (const char *dir)
49 {
50         if (g_file_test (dir, G_FILE_TEST_IS_DIR))
51                 return TRUE;
52         
53         if (g_mkdir (dir, 488) == 0)
54                 return TRUE;
55
56         if (errno == EEXIST)
57                 return g_file_test (dir, G_FILE_TEST_IS_DIR);
58         
59         g_warning ("Failed to create directory %s: %s", dir, strerror (errno));
60         return FALSE;
61 }
62
63 const gchar *
64 ev_dot_dir (void)
65 {
66         if (dot_dir == NULL) {
67                 gboolean exists;
68
69 #if WITH_GNOME
70                 dot_dir = g_build_filename (gnome_user_dir_get (),
71                                             "evince",
72                                             NULL);
73 #else
74                 dot_dir = g_build_filename (g_get_user_config_dir (),
75                                             "evince",
76                                             NULL);
77 #endif
78
79                 exists = ensure_dir_exists (dot_dir);
80                 if (!exists)
81                         exit (1);
82         }
83
84         return dot_dir;
85 }
86
87 const gchar *
88 ev_tmp_dir (void)
89 {
90         if (tmp_dir == NULL) {
91                 gboolean exists;
92                 gchar   *dirname;
93
94                 dirname = g_strdup_printf ("evince-%u", getpid ());
95                 tmp_dir = g_build_filename (g_get_tmp_dir (),
96                                             dirname,
97                                             NULL);
98                 g_free (dirname);
99
100                 exists = ensure_dir_exists (tmp_dir);
101                 g_assert (exists);
102         }
103
104         return tmp_dir;
105 }
106
107 void
108 ev_file_helpers_init (void)
109 {
110 }
111
112 void
113 ev_file_helpers_shutdown (void)
114 {       
115         if (tmp_dir != NULL)    
116                 g_rmdir (tmp_dir);
117
118         g_free (tmp_dir);
119         g_free (dot_dir);
120
121         dot_dir = NULL;
122         tmp_dir = NULL;
123 }
124
125 gchar * 
126 ev_tmp_filename (const gchar *prefix)
127 {
128         gchar *basename;
129         gchar *filename = NULL;
130
131         do {
132                 if (filename != NULL)
133                         g_free (filename);
134                         
135                 basename = g_strdup_printf ("%s-%d",
136                                             prefix ? prefix : "document",
137                                             count ++);
138                 
139                 filename = g_build_filename (ev_tmp_dir (),
140                                              basename, NULL);
141                 
142                 g_free (basename);
143         } while (g_file_test (filename, G_FILE_TEST_EXISTS));
144                         
145         return filename;
146 }
147
148 gboolean
149 ev_xfer_uri_simple (const char *from,
150                     const char *to,
151                     GError     **error)
152 {
153         GnomeVFSResult result;
154         GnomeVFSURI *source_uri;
155         GnomeVFSURI *target_uri;
156         
157         if (!from)
158                 return FALSE;
159         
160         source_uri = gnome_vfs_uri_new (from);
161         target_uri = gnome_vfs_uri_new (to);
162
163         result = gnome_vfs_xfer_uri (source_uri, target_uri, 
164                                      GNOME_VFS_XFER_DEFAULT | GNOME_VFS_XFER_FOLLOW_LINKS,
165                                      GNOME_VFS_XFER_ERROR_MODE_ABORT,
166                                      GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
167                                      NULL,
168                                      NULL);
169         gnome_vfs_uri_unref (target_uri);
170         gnome_vfs_uri_unref (source_uri);
171     
172         if (result != GNOME_VFS_OK)
173                 g_set_error (error,
174                              G_FILE_ERROR,
175                              G_FILE_ERROR_FAILED,
176                              gnome_vfs_result_to_string (result));
177         return (result == GNOME_VFS_OK);
178
179 }
180
181 /* Compressed files support */
182 #define BZIPCOMMAND "bzip2"
183 #define GZIPCOMMAND "gzip"
184 #define N_ARGS      4
185 #define BUFFER_SIZE 1024
186
187 static gchar *
188 compression_run (const gchar       *uri,
189                  EvCompressionType  type,
190                  gboolean           compress, 
191                  GError           **error)
192 {
193         gchar *argv[N_ARGS];
194         gchar *uri_dst = NULL;
195         gchar *filename, *filename_dst;
196         gchar *cmd;
197         gint   fd, pout;
198
199         if (type == EV_COMPRESSION_NONE)
200                 return NULL;
201
202         cmd = g_find_program_in_path ((type == EV_COMPRESSION_BZIP2) ? BZIPCOMMAND : GZIPCOMMAND);
203         if (!cmd)
204                 return NULL;
205
206         filename = g_filename_from_uri (uri, NULL, NULL);
207         if (!filename) {
208                 g_free (cmd);
209                 return NULL;
210         }
211         
212         filename_dst = g_build_filename (ev_tmp_dir (), "evinceXXXXXX", NULL);
213         fd = g_mkstemp (filename_dst);
214         if (fd < 0) {
215                 g_free (cmd);
216                 g_free (filename);
217                 g_free (filename_dst);
218                 return NULL;
219         }
220
221         argv[0] = cmd;
222         argv[1] = compress ? "-c" : "-cd";
223         argv[2] = filename;
224         argv[3] = NULL;
225
226         if (g_spawn_async_with_pipes (NULL, argv, NULL,
227                                       G_SPAWN_STDERR_TO_DEV_NULL,
228                                       NULL, NULL, NULL,
229                                       NULL, &pout, NULL, error)) {
230                 GIOChannel *in, *out;
231                 gchar buf[BUFFER_SIZE];
232                 GIOStatus read_st, write_st;
233                 gsize bytes_read, bytes_written;
234
235                 in = g_io_channel_unix_new (pout);
236                 g_io_channel_set_encoding (in, NULL, NULL);
237                 out = g_io_channel_unix_new (fd);
238                 g_io_channel_set_encoding (out, NULL, NULL);
239
240                 do {
241                         read_st = g_io_channel_read_chars (in, buf,
242                                                            BUFFER_SIZE,
243                                                            &bytes_read,
244                                                            error);
245                         if (read_st == G_IO_STATUS_NORMAL) {
246                                 write_st = g_io_channel_write_chars (out, buf,
247                                                                      bytes_read,
248                                                                      &bytes_written,
249                                                                      error);
250                                 if (write_st == G_IO_STATUS_ERROR)
251                                         break;
252                         } else if (read_st == G_IO_STATUS_ERROR) {
253                                 break;
254                         }
255                 } while (bytes_read > 0);
256
257                 g_io_channel_unref (in);
258                 g_io_channel_unref (out);
259         }
260
261         close (fd);
262
263         if (*error == NULL) {
264                 uri_dst = g_filename_to_uri (filename_dst, NULL, NULL);
265         }
266
267         g_free (cmd);
268         g_free (filename);
269         g_free (filename_dst);
270
271         return uri_dst;
272 }
273
274 gchar *
275 ev_file_uncompress (const gchar       *uri,
276                     EvCompressionType  type,
277                     GError           **error)
278 {
279         g_return_val_if_fail (uri != NULL, NULL);
280
281         return compression_run (uri, type, FALSE, error);
282 }
283
284 gchar *
285 ev_file_compress (const gchar       *uri,
286                   EvCompressionType  type,
287                   GError           **error)
288 {
289         g_return_val_if_fail (uri != NULL, NULL);
290
291         return compression_run (uri, type, TRUE, error);
292 }