ftp://ftp.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/gnome-vfs2-2.3.8-1.src.rpm
[gnome-vfs-httpcaptive.git] / test / test-symlinks.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* test-symlinks.c: verifies that symlinks are being created properly
3    Copyright (C) 2000 Eazel
4
5    The Gnome Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    The Gnome Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the Gnome Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.
19
20    Author: Seth Nickell <snickell@stanford.edu> */
21
22 #include <config.h>
23
24 #include <glib/gmain.h>
25 #include <libgnomevfs/gnome-vfs-async-ops.h>
26 #include <libgnomevfs/gnome-vfs-init.h>
27 #include <libgnomevfs/gnome-vfs-ops.h>
28 #include <popt.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 static GMainLoop *main_loop;
33
34 typedef struct {
35         GnomeVFSResult expected_result;
36         const char *uri;
37         const char *target_uri;
38         const char *target_reference;
39 } CallbackData;
40
41 static int measure_speed = 0;
42 static int sort = 0;
43 static int items_per_notification = 1;
44
45 struct poptOption options[] = {
46         {
47                 "chunk-size",
48                 'c',
49                 POPT_ARG_INT,
50                 &items_per_notification,
51                 0,
52                 "Number of items to send for every notification",
53                 "NUM_ITEMS"
54         },
55         {
56                 "measure-speed",
57                 'm',
58                 POPT_ARG_NONE,
59                 &measure_speed,
60                 0,
61                 "Measure speed without displaying anything",
62                 NULL
63         },
64         {
65                 "sort",
66                 's',
67                 POPT_ARG_NONE,
68                 &sort,
69                 0,
70                 "Sort entries",
71                 NULL
72         },
73         {
74                 NULL,
75                 0,
76                 0,
77                 NULL,
78                 0,
79                 NULL,
80                 NULL
81         }
82 };
83
84 static int
85 deal_with_result (GnomeVFSResult result, GnomeVFSResult expected_result, 
86         const char *uri, const char *target_uri, const char *target_reference, 
87         gboolean unlink) 
88 {
89         char read_buffer[1024];
90         const char *write_buffer = "this is test data...we should read the same thing";
91         GnomeVFSHandle *handle;
92         GnomeVFSFileSize bytes_written, temp;
93         GnomeVFSFileInfo info_uri = {0,};
94         GnomeVFSFileInfo info_target = {0,};
95         int return_value = 1;
96         const gchar *result_string;
97         GnomeVFSResult error;   
98         GnomeVFSURI *real_uri, *real_uri_target;
99         GnomeVFSFileInfo *info;
100
101         real_uri = gnome_vfs_uri_new (uri);
102         real_uri_target = gnome_vfs_uri_new (target_uri);
103
104         if (result != expected_result) {
105                 result_string = gnome_vfs_result_to_string (result);
106                 printf ("creating a link from %s to %s returned %s instead of %s.\n", uri, target_reference,
107                         result_string, gnome_vfs_result_to_string (expected_result));
108                 return_value = 0;
109         } else if (result == GNOME_VFS_OK) { 
110                 info = gnome_vfs_file_info_new();
111                 error = gnome_vfs_get_file_info_uri (real_uri, info, GNOME_VFS_FILE_INFO_DEFAULT);
112                 if ((error != GNOME_VFS_OK) || (info->type != GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK)) {
113                         printf ("Symlink problem: gnome_vfs_file_info returns wrong for link %s\n", uri);
114                 } else {
115                         /* our link seems to have been created correctly - lets see if its real */
116                         error = gnome_vfs_open_uri (&handle, real_uri_target, GNOME_VFS_OPEN_WRITE);
117                         if (error == GNOME_VFS_ERROR_NOT_FOUND) 
118                                 error = gnome_vfs_create_uri (&handle, real_uri_target, GNOME_VFS_OPEN_WRITE, 0, GNOME_VFS_PERM_USER_ALL);
119                         if (error == GNOME_VFS_OK) {
120                                 /* write stuff to our link location */
121                                 error = gnome_vfs_write (handle, write_buffer, strlen (write_buffer) + 1, &bytes_written);
122                                 error = gnome_vfs_close (handle);
123                                 error = gnome_vfs_open_uri (&handle, real_uri, GNOME_VFS_OPEN_READ);
124                                 if (error == GNOME_VFS_OK) {
125                                         error = gnome_vfs_read (handle, read_buffer, bytes_written, &temp);
126                                         read_buffer[temp] = 0;
127                                         error = gnome_vfs_close (handle);
128                                         if (strcmp (read_buffer, write_buffer) != 0) {
129                                                 printf ("Symlink problem: value written is not the same as the value read!\n");
130                                                 printf ("Written to %s: #%s# \nRead from link %s: #%s#\n", 
131                                                         target_uri, write_buffer, uri, read_buffer);
132                                                 return_value = 0;
133                                         }
134                                 }
135                         }
136                         gnome_vfs_get_file_info_uri (real_uri, &info_uri, GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
137                         gnome_vfs_get_file_info_uri (real_uri_target, &info_target, GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
138                         if (info_uri.inode != info_target.inode) {
139                                 printf ("Symlink problem: link following is not working\n");
140                                 printf ("File: %s   Link: %s\n", target_uri, uri);
141                         }
142                         gnome_vfs_file_info_clear (&info_uri);
143                         gnome_vfs_get_file_info_uri (real_uri, &info_uri, GNOME_VFS_FILE_INFO_DEFAULT);
144                         gnome_vfs_file_info_clear (&info_target);
145                         gnome_vfs_get_file_info_uri (real_uri_target, &info_target, GNOME_VFS_FILE_INFO_DEFAULT);
146                         if (info_uri.inode == info_target.inode) {
147                                 printf ("Symlink problem: link following is happening when it shouldn't be.\n");
148                                 printf ("File: %s   Link: %s\n", target_uri, uri);
149                         }
150                         gnome_vfs_file_info_clear (&info_uri);
151                         gnome_vfs_file_info_clear (&info_target);
152                 }
153                 gnome_vfs_file_info_unref (info);
154                 if (unlink) {
155                         gnome_vfs_unlink_from_uri (real_uri_target);
156                         error = gnome_vfs_unlink_from_uri (real_uri);
157                         if (error != GNOME_VFS_OK) {
158                                 printf ("Problem unlinking URI %s", uri);
159                         }
160                 }
161         }
162
163
164         gnome_vfs_uri_unref (real_uri);
165         gnome_vfs_uri_unref (real_uri_target);
166
167         return return_value;
168 }
169
170 static void
171 create_link_callback (GnomeVFSAsyncHandle *handle,
172                       GnomeVFSResult result,
173                       gpointer callback_data)
174 {
175         const char *uri, *target_uri, *target_reference;
176         GnomeVFSResult expected_result;
177         CallbackData *info;
178
179         info = (CallbackData*) callback_data;
180         
181         uri = info->uri;
182         target_uri = info->target_uri;
183         expected_result = info->expected_result;
184         target_reference = info->target_reference;
185
186         deal_with_result (result, expected_result, uri, target_uri, target_reference, TRUE);    
187
188         g_free (callback_data);
189         g_main_loop_quit (main_loop);
190 }
191
192
193 static int
194 make_link (const char *uri, const char *target_reference, const char *target_uri, GnomeVFSResult expected_result, gboolean unlink)
195 {
196         GnomeVFSURI *real_uri, *real_uri_target;
197         GnomeVFSResult result;
198
199         int return_value = 1;
200
201         real_uri = gnome_vfs_uri_new (uri);
202         real_uri_target = gnome_vfs_uri_new (target_uri);
203
204         result = gnome_vfs_create_symbolic_link (real_uri, target_reference);
205
206         return_value = deal_with_result(result, expected_result, uri, target_uri, target_reference, unlink);
207
208
209         
210         gnome_vfs_uri_unref (real_uri);
211         gnome_vfs_uri_unref (real_uri_target);
212
213         return return_value;
214 }
215
216 static void
217 make_link_async (const char *uri, const char *target_reference, const char *target_uri, GnomeVFSResult expected_result)
218 {
219         CallbackData *info;
220         GnomeVFSAsyncHandle *handle;
221
222         info = g_malloc (sizeof (CallbackData));
223         info->uri = uri;
224         info->target_uri = target_uri;
225         info->expected_result = expected_result;
226         info->target_reference = target_reference;
227
228         gnome_vfs_async_create_symbolic_link (&handle, gnome_vfs_uri_new(uri), target_reference, 0, create_link_callback, info);
229 }
230
231 static void
232 check_broken_links (const char *uri)
233 {
234         GnomeVFSHandle *handle;
235         GnomeVFSResult error;
236         GnomeVFSURI *real_uri, *real_uri_target;
237
238         real_uri = gnome_vfs_uri_new (uri);
239         real_uri_target = gnome_vfs_uri_new ("file:///tmp/deadlink");
240
241         gnome_vfs_unlink_from_uri (real_uri_target);
242         gnome_vfs_create_symbolic_link (real_uri, "deadlink");
243
244         error = gnome_vfs_open_uri (&handle, real_uri, GNOME_VFS_OPEN_READ);
245         if (error != GNOME_VFS_ERROR_NOT_FOUND) {
246                 printf ("GNOME_VFS_BROKEN_SYMLINK not returned open attempting to open a broken symlink.\n");
247                 printf ("Value returned: %d\n", error);
248         }
249
250         gnome_vfs_unlink_from_uri (real_uri);
251         gnome_vfs_unlink_from_uri (real_uri_target);
252
253         gnome_vfs_uri_unref (real_uri);
254         gnome_vfs_uri_unref (real_uri_target);
255 }
256
257
258 int
259 main (int argc, const char **argv)
260 {
261         GnomeVFSURI *directory, *file_to_delete;
262
263         poptContext popt_context;
264
265         popt_context = poptGetContext ("test-vfs", argc, argv,
266                                        options, 0);
267
268         if (argc != 2) {
269                 fprintf (stderr, "Usage: %s <directory>\n", argv[0]);
270                 return 1;
271         }
272
273         gnome_vfs_init ();
274         directory = gnome_vfs_uri_new ("file:///tmp/tmp");
275
276         gnome_vfs_make_directory_for_uri (directory, GNOME_VFS_PERM_USER_ALL);
277
278         make_link ("file:///tmp/link_to_ditz", "file:///tmp/ditz", "file:///tmp/ditz", GNOME_VFS_OK, TRUE);
279         make_link ("file:///tmp/link_to_ditz_relative", "ditz", "file:///tmp/ditz", GNOME_VFS_OK, TRUE);
280         make_link ("file:///tmp/tmp/link_to_ditz", "../ditz", "file:///tmp/ditz", GNOME_VFS_OK, FALSE);
281         make_link ("file:///tmp/link_to_link", "tmp/link_to_ditz", "file:///tmp/tmp/link_to_ditz", GNOME_VFS_OK, TRUE);
282                                 
283         gnome_vfs_remove_directory_from_uri (directory);
284         gnome_vfs_uri_unref (directory);
285
286         file_to_delete = gnome_vfs_uri_new ("file:///tmp/ditz");
287         gnome_vfs_unlink_from_uri (file_to_delete);
288         gnome_vfs_uri_unref (file_to_delete);
289
290         check_broken_links("file:///tmp/link");
291
292         make_link ("file:///tmp/link_to_ditz_offfs", "http://www.a.com/ditz", "http://www.a.com/ditz", GNOME_VFS_ERROR_NOT_SUPPORTED, TRUE);
293         make_link ("http://www.eazel.com/link_to_ditz", "file:///tmp/ditz", "file:///tmp/ditz", GNOME_VFS_ERROR_NOT_SUPPORTED, TRUE);
294         make_link ("http://www.a.com/link_to_ditz_relative", "ditz", "http://www.a.com/ditz", GNOME_VFS_ERROR_NOT_SUPPORTED, TRUE);
295
296         make_link_async ("file:///tmp/async_link", "file:///tmp/link", "file:///tmp/link", GNOME_VFS_OK);
297
298         main_loop = g_main_loop_new (NULL, TRUE);
299         g_main_loop_run (main_loop);
300         g_main_loop_unref (main_loop);
301
302         return 0;
303 }